Django 部署基礎【使用 Nginx + uWSGI 的方式來部署來 Django】

本文主要講解在 Linux 平臺下,使用 Nginx + uWSGI 的方式來部署來 Django,這是目前比較主流的方式。當然你也可以使用 Gunicorn 代替 uWSGI,不過原理都是類似的,弄懂了其中一種,其它的方式理解起來問題也不會很大。

?

有很多人曾經在郵件中咨詢過問我如何部署,部署確實對開發者有著較高的要求,尤其是初學者來說,部署比較難,這很正常,千萬不要輕易就放棄了

?

回想我2013年剛開始接觸也是一頭霧水,整整弄了四五天才完全搞懂,部署好了真是欣喜若狂。我自認為算不上聰明,我都能搞明白,你也一定能行。最關鍵和寶貴的品質就是堅持不懈和勇于試錯。下面就讓我們一起開始正式的部署教程吧。

?

基礎知識儲備

當我們發現用瀏覽器不能訪問的時候,我們需要一步步排查問題。

整個部署的鏈路是 Nginx -> uWSGI -> Python Web程序,通常還會提到supervisord工具。

uWSGI是一個軟件,部署服務的工具,了解整個過程,我們先了解一下WSGI規范,uwsgi協議等內容。

?

WSGI(Web Server Gateway Interface)規范,WSGI規定了Python Web應用和Python Web服務器之間的通訊方式。

目前主流的Python Web框架,比如Django,Flask,Tornado等都是基于這個規范實現的。

?

uwsgi協議是uWSGI工具獨有的協議,簡潔高效的uwsgi協議是選擇uWSGI作為部署工具的重要理由之一,詳細的 uwsgi協議 可以參考uWSGI的文檔。

uWSGI是 實現了uwsgi協議,WSGI規范和HTTP協議的 一個C語言實現的軟件。

?

Nginx是一個Web服務器,是一個反向代理工具,我們通常用它來部署靜態文件。主流的Python Web開發框架都遵循WSGI規范。

uWSGI通過WSGI規范和我們編寫的服務進程通訊,然后通過自帶的高效的 uwsgi 協議和 Nginx進行通訊,最終Nginx通過HTTP協議將服務對外透出。

當一個訪問進來的時候,首先到 Nginx,Nginx會把請求(HTTP協議)轉換uwsgi協議傳遞給uWSGI,uWSGI通過WSGI和web server進行通訊取到響應結果,再通過uwsgi協議發給Nginx,最終Nginx以HTTP協議發現響應給用戶。

有些同學可能會說,uWSGI不是支持HTTP協議么,也支持靜態文件部署,我不用Nginx行不行?

當然可以,這么做沒問題,但目前主流的做法是用Nginx,畢竟它久經考驗,更穩定,當然也更值得我們信賴。

?

supervisor?是一個進程管理工具。任何人都不能保證程序不異常退出,不別被人誤殺,所以一個典型的工程做法就是使用supervisor看守著你的進程,一旦異常退出它會立馬進程重新啟動起來。

如果服務部署后出現異常,不能訪問。我們需要分析每一步有沒有問題,這時候就不得不用到Linux中一些命令。

?

進程分析

進程是計算機分配資源的最小單位,我們的程序至少是運行在一個進程中。

1. 查看進程信息

通常我們使用 ps aux | grep python 來查看系統中運行的 python 進程,輸出結果如下:

tu@linux / $ ps uax | grep python

USER ? ? ? PID %CPU %MEM ? ?VSZ ? RSS TTY ? ? ?STAT START ? TIME COMMAND

root ? ? ?1780 ?0.0 ?0.0 ?58888 10720 ? ? ? ? ?Ss ? Jan15 ? 8:46 /usr/bin/python /usr/local/bin/supervisord -c /etc/supervisord.conf

tu ? ? ?4491 ?0.0 18.0 3489820 2960628 ? ? ? Sl ? Jan29 ? 0:19 python a.py

tu ? ? 12602 ?5.3 26.4 4910444 4343708 pts/1 Sl+ ?12:34 ? 4:07 python b.py

有些同學習慣使用 ps -ef | grep xxx 結果也是類似的,讀者可以自行嘗試。

?

輸出結果中 USER 后面的 PID 代表進程編號。

我們可以通過查看 /proc/PID/ 目錄的文件信息來得到這個進程的一些信息(Linux中一切皆文件,進程信息也在文件中),比如它是在哪個目錄啟動的,啟動命令是什么等信息。執行命令后輸入內容如下:

tu@linux /proc/4491 $?sudo ls -ahl

...

dr-xr-xr-x ? 2 tu tu 0 Feb 17 13:32 attr

-rw-r--r-- ? 1 tu tu 0 Feb 17 13:32 autogroup

-r-------- ? 1 tu tu 0 Feb 17 13:32 auxv

-r--r--r-- ? 1 tu tu 0 Feb 17 13:32 cgroup

--w------- ? 1 tu tu 0 Feb 17 13:32 clear_refs

-r--r--r-- ? 1 tu tu 0 Feb 17 12:49 cmdline ?這個文件中有啟動進程具體的命令

-rw-r--r-- ? 1 tu tu 0 Feb 17 13:32 comm

-rw-r--r-- ? 1 tu tu 0 Feb 17 13:32 coredump_filter

-r--r--r-- ? 1 tu tu 0 Feb 17 13:32 cpuset

lrwxrwxrwx ? 1 tu tu 0 Feb 17 13:32 cwd -> /home/tu ?啟動進程時的工作目錄

-r-------- ? 1 tu tu 0 Feb 17 13:32 environ ?進程的環境變量列表

lrwxrwxrwx ? 1 tu tu 0 Feb 17 12:00 exe -> /usr/bin/python2.7 鏈接到進程的執行命令文件

...省去了部分內容

?

2. 向進程發送信號

我們可以使用 kill PID 殺死一個進程,或者使用 kill -9 PID 強制殺死一個進程。

記得以前在研究生的時候師弟和師妹經常問我,kill -9 里面的 -9 是什么意思,我告訴他們,這是強制殺死進程的意思,讓這個進程“九死一生”。當然這是開玩笑,這里的 -9 是信號的一種,kill 命令會向進程發送一個信號,-9代表 SIGKILL 之意,用于強制終止某個進程,當然這是一種無情地,野蠻地方式干掉進程。

我們可以通過 kill -l 命令查看到所有的信號

HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS

?

上面的信號是有順序的,比如第1個是 HUP,第9個是 KILL,下面兩種方式是等價的:

kill -1 PID 和 kill -HUP PID

kill -9 PID 和 kill -KILL PID

信號HUP通常程序用這個信號進行優雅重載配置文件,重新啟動并且不影響正在運行的服務。比如

pkill -1 uwsgi 優雅重啟uwsgi 進程,對服務器沒有影響

kill -1 NGINX_PID 優雅重啟nginx進程,對服務器沒有影響

除了知道可以這么使用之外,感興趣的讀者還可以自行學習,深入了解下uwsgi和nginx無損reload的機制。

我們常用CTRL+C中斷一個命令的執行,其實就是發送了一個信號到該進程

CTRL-C 發送 SIGINT 信號給前臺進程組中的所有進程,常用于終止正在運行的程序。

CTRL-Z 發送 SIGTSTP 信號給前臺進程組中的所有進程,常用于掛起一個進程。

每個程序可能對部分信號的功能定義不一致,其它信號的含義大家可以自行學習。

?

3. 查看進程打開了哪些文件

sudo lsof -p PID

如果是分析一個你不太了解的進程,這個命令比較有用。

可以使用 lsof -p PID | grep TCP 查看進程中的 TCP 連接信息。

?

4. 查看文件被哪個進程使用

使用這個命令查看一個文件被哪些進程正在使用 sudo lsof /path/to/file,示例如下:

> sudo lsof /home/tu/.virtualenvs/mic/bin/uwsgi

COMMAND ? PID USER ?FD ? TYPE DEVICE SIZE/OFF ? ? NODE NAME

uwsgi ? ?2071 tu txt ? ?REG 253,17 ?1270899 13240576 /home/tu/.virtualenvs/mic/bin/uwsgi

uwsgi ? 13286 tu txt ? ?REG 253,17 ?1270899 13240576 /home/tu/.virtualenvs/mic/bin/uwsgi

uwsgi ? 13287 tu txt ? ?REG 253,17 ?1270899 13240576 /home/tu/.virtualenvs/mic/bin/uwsgi

uwsgi ? 13288 tu txt ? ?REG 253,17 ?1270899 13240576 /home/tu/.virtualenvs/mic/bin/uwsgi

?

5. 查看進程當前狀態

當我們發現一個進程啟動了,端口也是正常的,但好像這個進程就是不“干活”。比如我們執行的是數據更新進程,這個進程不更新數據了,但還是在跑著。可能數據源有問題,可能我們寫的程序有BUG,也可能是更新時要寫入到的數據庫出問題了(數據庫連接不上了,寫數據死鎖了)。我們這里主要說下第二種,我們自己的程序如果有BUG,導致工作不正常,我們怎么知道它當前正在干什么呢,這時候就要用到Linux中的調試分析診斷strace,可以使用?sudo strace -p PID這個命令。

通過執行后輸出的一些信息,推測分析看是哪些出了問題。

?

這里我們講了一些進程分析的工具和方法,關于進程分析工具和方法還有許多,大家需要不斷練習,熟練運用這些工具去排查遇到的問題。

?

端口分析

比如我們在服務器上運行 Nginx,訪問的時候就是連接不上,我們可以使用 ps aux | grep nginx看下nginx進程是不是啟動了,也可以看下 80端口有沒有被占用。換句話說,如果沒有任何程序跑在這個端口上(或者說沒有任何程序使用這個端口),證明忘了啟動相關程序或者沒能啟動成功,或者說程序使用的端口被修改了,不是80了,那又怎么可能能訪問到呢?

1. 查看全部端口占用情況

Linux中我們可以使用 netstat 工具來進程網絡分析,netstat 命令有非常多選項,這里只列出了常用的一部分

-a或--all 顯示所有連接中的Socket,默認不顯示 LISTEN 相關的。

-c或--continuous 持續列出網絡狀態,不斷自動刷新輸出。

-l或--listening 顯示監聽中的服務器的Socket。

-n或--numeric 直接使用IP地址,而不是展示域名。

-p或--programs 顯示正在使用Socket的程序進程PID和名稱。

-t或--tcp 顯示TCP傳輸協議的連接。

-u或--udp 顯示UDP傳輸協議的連接。

比如我們可以查看服務器中監控了哪些端口,如果我們的nginx是使用80端口,uwsgi使用的是7001端口,我們就能知道通過下面的命令

> netstat -nltp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address ? ? ? ? ? Foreign Address ? ? ? ? State ? ? ? PID/Program name

tcp ? ? ? ?0 ? ? ?0 0.0.0.0:7001 ? ? ? ? ? ?0.0.0.0:* ? ? ? ? ? ? ? LISTEN ? ? ?2070/uwsgi ? ? ?

tcp ? ? ? ?0 ? ? ?0 127.0.0.1:6379 ? ? ? ? ?0.0.0.0:* ? ? ? ? ? ? ? LISTEN ? ? ?1575/redis-server 1

就能知道80端口的 nginx 是不是啟動成功了,7001端口的uwsgi是不是啟動成功了。

注意:如果PID和Program Name顯示不出來,證明是權限不夠,可以使用sudo運行

2. 查看具體端口占用情況

> sudo lsof -i :80 (注意端口80前面有個英文的冒號)

COMMAND ? ?PID ? ? USER ? FD ? TYPE DEVICE SIZE/OFF NODE NAME

nginx ? 4123 ? admin ? ?3u ?IPv4 ?13031 ? ? ?0t0 ?TCP *:http (LISTEN)

nginx ? 4124 ? admin ? ?3u ?IPv4 ?13031 ? ? ?0t0 ?TCP *:http (LISTEN)

我們可以通過這個方法查詢出占用端口的程序,如果遇到端口已經被占用,原來的進程沒有正確地終止,可以使用kill命令停掉原來的進程,這樣我們就又可以使用這個端口了。

?

除了上面講的一些命令,在部署過程中會經常用到下面的一些Linux命令,如果不清楚它們是做什么的,可以提前自行學習下這些Linux基礎命令:

ls, touch, mkdir, mv, cp, ps, chmod, chown

學習完了這些內容,我們應該就具備了部署Linux服務器的基礎知識了,在遇到問題后,應該也會有一些調查思路。

剩余部分大家再去?自強學堂上看?Django部署,應該會容易懂的多。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/456845.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/456845.shtml
英文地址,請注明出處:http://en.pswp.cn/news/456845.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

css的屬性是變量是怎么表達,CSS自定義屬性(變量)

Github上有個叫electron-api-demos的項目,看代碼的時候發現了這么一個css文件(variables.css)::root {--color: hsl(0,0%,22%);--color-subtle: hsl(0,0%,44%);--color-strong: hsl(0,0%,11%);--color-link: hsl(0,0%,22%);--color-border: hsl(0,0%,88%…

Exception in thread main java.lang.UnsupportedClassVersionError的另類解決辦法

最近在Linux虛擬機上跑在windows平臺上的eclipes打出來的jar包時報出Exception in thread “main” java.lang.UnsupportedClassVersionError的錯誤: 經過上網查詢了解到是因為自己Windows使用的是jdk1.8版本,而Linux使用的是jdk1.7版本,所…

Linux命令【第一篇】

1、創建一個目錄/data 記憶方法:英文make directorys縮寫后就是mkdir。 命令: mkdir /data 或 cd /;mkdir data #提示:使用分號可以在一行內分割兩個命令。 實踐過程: 方法一: [rootoldboy66 ~]# mkdir /data #查…

Jenkins + gitlab webhook實現自動化部署

1、先在Jenkins安裝插件Gitlab Hook Plugin 和Build Authorization Token Root Plugin;2.插件安裝完成后在任務里添加token3、在gitlab上添加鉤子4、點擊測試鉤子或push代碼再看Jenkins已經在構建了就說明成功了(也可以在瀏覽器直接執行這個URL&#xff…

多繼承以及MRO順序【super().的使用】

多繼承以及MRO順序 1. 單獨調用父類的方法 # codingutf-8print("******多繼承使用類名.__init__ 發生的狀態******") class Parent(object):def __init__(self, name):print(parent的init開始被調用)self.name nameprint(parent的init結束被調用)class Son1(Paren…

人工智能專業詞匯集

最近看到一篇關于AI專業詞匯總結的文章,感覺不錯,分享一下。 對應的詞匯項目地址為:https://github.com/jiqizhixin/Artificial-Intelligence-Terminology 本詞匯庫目前擁有的專業詞匯共計 500 個,主要為機器學習基礎概念和術語…

js 當前日期增加自然月

js 在日期不滿足的情況下就會自動加1個月,比如在當前時間為3月31號,傳入1,1兩個參數,預期結果為2月29日,但是結果輸出了3月2日。就是如果不滿就會溢出到下個月,后來看了api發現了setMonth有兩個方法&#x…

好雨云幫如何對接Git Server

前言 云幫目前支持對接GitLab、Gogs、Github,或者主流代碼托管平臺的公開項目,后期會考慮接入其他類型的Git服務。 私有云 GitLab是一個用于倉庫管理系統的開源項目,私有云服務里使用比較多的自建Git服務。 對接GitLab 通過應用市場進行安裝Gitlab 安裝G…

Python 生成requirement 使用requirements.txt

python項目中必須包含一個 requirements.txt 文件,用于記錄所有依賴包及其精確的版本號。以便新環境部署。requirements.txt可以通過pip命令自動生成和安裝生成requirements.txt文件 pip freeze > requirements.txt安裝requirements.txt依賴 pip install -r requ…

Source Insight上手教程

目錄Project的建立和工作區域同步查看定義查找引用查找調用Source Insight常用快捷鍵 目錄 最近剛參加工作,第一個任務就是查看項目的源碼,熟悉代碼結構。于是乎就簡單學習了Source Insight。在這里就轉載別人的文章當做自己的筆記,便于自己…

微信禁用右上角的分享按鈕,WeixinJSBridge API以及隱藏分享的子按鈕等菜單項

今天在做隱藏微信右上角的分享按鈕 百度查到的一串代碼&#xff0c;挺好用的 <!--禁用微信分享按鈕--><script>function onBridgeReady() {WeixinJSBridge.call(hideOptionMenu);}if (typeof WeixinJSBridge "undefined") {if (document.addEventListen…

python2.7無法使用pip(安裝easy_install)

python27和python36 共存時安裝pip方法&#xff0c;解決python27文件夾下沒有script文件方法 報錯&#xff1a; D:\PYTHON2.7>python ez_setup.py Downloading http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg Traceback (most recent call…

Codeforces 754E:Dasha and cyclic table

Codeforces 754E&#xff1a;Dasha and cyclic table 題目鏈接&#xff1a;http://codeforces.com/problemset/problem/754/E 題目大意&#xff1a;$A$矩陣&#xff08;$size(A)n \times m$&#xff0c;僅含a-z&#xff09;在整個平面做周期延拓&#xff0c;問$B$矩陣&#xff…

位運算中的左移和右移的計算詳解

最近在學習javaScrapt&#xff0c;在學到位運算符這部分的時候&#xff0c;突然發現看不懂書上的例子了。經過查找資料后&#xff0c;發現了一遍不錯的文章。分享一下&#xff1a; 正數的左移和右移 以3為例 3的二進制為 00000011 右移2位的時候將最右的11去掉左邊補00結果…

AC日記——字符串P型編碼 openjudge 1.7 31

31:字符串p型編碼 總時間限制: 1000ms內存限制: 65536kB描述給定一個完全由數字字符&#xff08;0,1,2,…,9&#xff09;構成的字符串str&#xff0c;請寫出str的p型編碼串。例如&#xff1a;字符串122344111可被描述為"1個1、2個2、1個3、2個4、3個1"&#xff0c;因…

javascript中的define用法

文章目錄1. AMD的由來2. AMD是什么3. AMD實例&#xff1a;如何定義一個模塊4. 匿名模塊5. 僅有一個參數的define6. Dojo中的AMD7. 結論最近由于工作需求只能快速學習JS&#xff0c;但在看代碼的時候發現許多東西都有疑問比如說代碼剛開始的define關鍵字的用法&#xff0c;剛好最…

解決:pip警告!DEPRECATION: The default format will switch to columns in the future.

pip警告&#xff01; DEPRECATION: The default format will switch to columns in the future. You can use --format(legacy|columns) (or define a format(legacy|columns) in your pip.conf under the [list] section) to disable this warning. pip升級到9.0.1后 查看pi…

PLSQL安裝配置

&#xff08;1&#xff09;解壓&#xff1a;plsql developer Oracle數據庫開發工具首先確保有oracle數據庫或者有oracle服務器&#xff0c;然后才能使用PLSQL Developer連接數據庫。&#xff08;2&#xff09;工具---首選項---連接----輸入OCI庫&#xff08;設置之后不用再裝or…

Mysql 學習筆記2

&#xff08;1&#xff09;MySQL查看表占用空間大小 //先進去MySQL自帶管理庫&#xff1a;information_schema //自己的數據庫&#xff1a;dbwww58com_kuchecarlib //自己的表&#xff1a;t_carmodelparamvalue mysql> use information_schema; Database changed mysql&g…

python程序打包為exe可執行文件

大家都知道&#xff0c;Python是一種腳本語言&#xff0c;也就是解釋型的語言&#xff0c;需要解釋器來進行解釋以后才可以執行&#xff0c;而Python源代碼需要在Python虛擬機上面運行&#xff0c;但是我們做好的程序&#xff0c;不可能給用戶使用的時候還讓他安裝一個Python環…