【Django】Uwsgi+Nginx+Django2.0+Python3.7實現高併發,多執行緒,高效能
一、系統以及環境
伺服器系統:Ubuntu 16.04
專案環境:python 3.7
框架:Django2.0
伺服器環境:Uwsgi、Nginx
效能監測工具:Uwsgitop
使用背景:因為Django自帶的伺服器沒通過安全稽核,而且效能低下,原生為單執行緒執行,不足以應對多執行緒,高併發的需求。
二、安裝相關環境
- 首先將系統中的python環境安裝或升級到python3.7(一般情況下,Ubuntu系統已經自帶了python 2.x的的環境,但是因為2.x的python離現在的時代有些久遠了,所以使用3.x的版本),具體操作請問度娘
- 安裝Django框架,具體安裝方法請問度娘。伺服器資源比較充裕的,可以安裝一個PyCharm開發工具,度娘上面有破解版的,這個工具還算是比較智慧化的,不過我是在客戶機上面開發好專案再上傳到伺服器的,因為我的資源比較不充裕。
- 安裝uwsgi,開啟系統的終端,執行命令:
pip install uwsgi
進行安裝uwsgi工具,稍等片刻就安裝好了 - 基於APT源安裝Nginx,在終端裡面輸入並執行:
sudo apt-get install nginx
,預設目錄解說如下:
/usr/sbin/nginx:
主程式
/etc/nginx:
存放配置檔案
/usr/share/nginx:
存放靜態檔案
/var/log/nginx:
存放日誌 - 安裝uwsgi負載監測工具Uwsgitop,在終端裡面輸入並執行:
pip install uwsgitop
三、建立並修改Django專案
-
開啟PyCharm這個開發工具,建立一個Django專案,等待專案載入完畢之後,執行以下命令
生成專案依賴檔案
pip freeze > requirements.txt
上傳到伺服器的時候,cd
到專案的根路徑的時候,輸入以下命令執行專案依賴檔案的安裝
pip install -r requirements.txt
上面這兩句命令就是為了讓系統環境統一
然後在PyCharm開發工具的終端嘗試使用python manage.py runserver 0.0.0.0:8000
來執行專案,然後到本地瀏覽器去輸入http://127.0.0.1:8000
看看能否跳出Django的歡迎頁面,如果能跳出就繼續往下看,如果不能,就先讓專案跑起來。 -
在專案的根路徑裡面(與
manage.py
檔案同級)建立一個uwsgi.xml
檔案,如下圖所示,這個檔案存在的意義就是讓你伺服器安裝好的uwsgi工具可以對你的專案進行相關配置,具體內容如下
<uwsgi>
<socket>:8000</socket><!-- 與nginx通訊的埠-->
<!--<http>:8000</http>-->
<chdir>/(xxx專案的上級路徑)/XXX</chdir>
<module>YYY.wsgi</module><!--wsgi.py檔案所在的位置-->
<processes>4</processes> <!-- 程序數 -->
<threads>2</threads> <!-- 執行緒數 -->
<disable-logging>false</disable-logging> <!-- true只記錄uwsgi錯誤和內部訊息,不記錄常規請求資訊,false反之-->
<daemonize>/(uwsgi資料夾的上級路徑)/uwsgi/uwsgi.log</daemonize><!--記錄請求日誌的檔案所在的位置-->
<!--<socket>/(uwsgi資料夾的上級路徑)/uwsgi/uwsgi.sock</socket>--><!--與nginx工具通訊的所在位置-->
<pidfile>/(uwsgi資料夾的上級路徑)/uwsgi/uwsgi.pid</pidfile><!--對uwsgi程序管理的檔案所在的位置-->
<stats>/(uwsgi資料夾的上級路徑)/uwsgi/uwsgi.status</stats><!--對uwsgi負載情況記錄的檔案所在的位置-->
<master>true</master><!--開啟主執行緒-->
<vacuum>true</vacuum><!--true當伺服器退出的時候自動清理環境,刪除unix socket檔案和pid檔案,false反之-->
<buffer-size>65535</buffer-size><!--uwsgi的最大快取-->
</uwsgi>
- 修改Django專案中的
setting.py
檔案,首先吧DEBUG=True
改成DEBUG=False
切換為生產模式,並在setting.py
檔案裡面的空白地方填入一下內容,然後記得在把專案上傳到服務端之後,記得先cd到專案的根路徑,然後執行Python manage.py collectstatic
把所有的靜態資源取出來做全域性靜態資源,不然,NGINX 那裡無法配置靜態資源路徑喔
STATIC_ROOT = os.path.join(BASE_DIR, 'static_all')
STATIC_URL = '/static/'
STATIC_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
到此,我們的專案就建立完畢了
四、修改服務端的nginx工具
-
登入服務端,我這裡採用的是阿里雲的學生ECS伺服器(才9.9元/月,條件好的,不建議採用這個伺服器,因為它真的是不好用,太卡了,只是我資金不足,就只能採用這個伺服器了,點我進入購買阿里雲伺服器)
-
開啟終端輸入
cd /etc/nginx
,回車,然後輸入ls ./
,回車,看看有沒有存在nginx.conf
這個檔案,如果沒有,那可能是你沒安裝好這個工具,這時候就得請萬能的度娘幫你解決找不到這個檔案的問題了 -
找到檔案之後,在終端裡面繼續輸入
vim nginx.conf
來開啟這個檔案,然後按一下鍵盤上的i
鍵就可以輸入字元了,如果這個檔案的第一行存在user
的,就把後面的欄位改為root
,如果不存在的,就寫user root
到這個檔案的第一行,然後找到http{ }
標籤,並在裡面加入以下程式碼
server{
listen 80;#暴露給外網的埠
server_name localhost;#伺服器ip
charset utf-8;#為了避免中文亂碼
access_log off:
location /static{
alias /(xxx專案的上級路徑)/XXX/static_all;#這個路徑就是在setting.py檔案中寫下的STATIC_ROOT的絕對路徑
}
location /{
uwsgi_pass 127.0.0.1:8000;#這個是在專案中的uwsgi.xml配置好的http請求路徑和埠
include /etc/nginx/uwsgi_params;
}
location=/favicon.ico{
log_not_found off;
access_log off;
root html;
}
}
然後按一下鍵盤上的Esc
鍵,再在英文狀態下輸入:wq
,點選回車鍵進行儲存輸入的內容
到此,nginx工具就部署好了,現在把專案上傳到伺服器。
五、建立uwsgi的相關檔案
在XXX(你的資料夾)中輸入mkdir
建立一個uwsgi
資料夾,並cd到這個資料夾,然後依次執行touch uwsgi.log
,touch uwsgi.pid
,touch uwsgi.sock
,touch uwsgi.status
來建立(上面配置uwsgi.xml檔案中所說的四個檔案)四個uwsgi檔案,然後回到你專案的根目錄
六、執行專案
-
先cd到專案的根路徑,在終端中輸入
uwsgi -x uwsgi.xml
,先載入專案中的uwsgi配置資訊,然後再執行/etc/init.d/nginx start
來執行nginx工具就把專案執行起來了 -
在你的瀏覽器裡面輸入"http://外網IP:埠",例如:
http://47.107.1.205:80
就能看到你部署的Django專案了
七、相關命令
1. /etc/init.d/nginx start 啟動nginx服務
2. /etc/init.d/nginx restart 重啟nginx 服務
3. /etc/init.d/nginx stop 停止nginx 服務
針對uwsgi.pid檔案
4. uwsgi -x uwsgi/uwsgi.xml # uwsgi.xml方式啟動
5. uwsgi --ini uwsgi/uwsgi.ini # uwsgi.ini方式啟動
6. uwsgi --reload uwsgi/uwsgi.pid # 重啟
7. uwsgi --stop uwsgi/uwsgi.pid # 關閉
八、uwsgi.ini方式的配置檔案
uwsgi的配置有好幾種方式,常用的就是ini和xml
[uwsgi]#這個必寫
uid = nginx #使用nginx使用者和組
gid = nginx
chdir = /webser/www/demosite #指定專案目錄,在配置多站點時,不要啟用
module = demosite.wsgi #載入demosite/wsgi.py這個模組,在配置多站點時,不要啟用
master = true #啟動主程序。
processes = 2 #啟動2個工作程序
listen = 120 #設定socket的監聽佇列大小(預設:100)
socket = /test/myapp.sock #指定socket檔案,也可以指定為127.0.0.1:9000,這樣就會監聽到網路套接字
pidfile = /var/run/uwsgi.pid #指定pid檔案
vacuum = true #當伺服器退出的時候自動刪除unix socket檔案和pid檔案。
enable-threads = true #允許用內嵌的語言啟動執行緒。這將允許你在app程式中產生一個子執行緒
buffer-size = 32768 #設定用於uwsgi包解析的內部快取區大小為64k。預設是4k。
reload-mercy = 8 #設定在平滑的重啟(直到接收到的請求處理完才重啟)一個工作子程序中,等待這個工作結束的最長秒數。這個配置會使在平滑地重啟工作子程序中,如果工作程序結束時間超過了8秒就會被強行結束(忽略之前已經接收到的請求而直接結束)
max-requests = 5000 #為每個工作程序設定請求數的上限。當一個工作程序處理的請求數達到這個值,那麼該工作程序就會被回收重用(重啟)。你可以使用這個選項來默默地對抗記憶體洩漏
limit-as = 256 #通過使用POSIX/UNIX的setrlimit()函式來限制每個uWSGI程序的虛擬記憶體使用數。這個配置會限制uWSGI的程序佔用虛擬記憶體不超過256M。如果虛擬記憶體已經達到256M,並繼續申請虛擬記憶體則會使程式報記憶體錯誤,本次的http請求將返回500錯誤。
harakiri = 60 #一個請求花費的時間超過了這個harakiri超時時間,那麼這個請求都會被丟棄,並且當前處理這個請求的工作程序會被回收再利用(即重啟)
daemonize = /var/log/myapp_uwsgi.log # 使程序在後臺執行,並將日誌打到指定的日誌檔案或者udp伺服器
disable-logging = true # 不記錄請求資訊的日誌。只記錄錯誤以及uWSGI內部訊息到日誌中
九、相關問題
- 出現!!! no internal routing support, rebuild with pcre support !!!這個問題
pip uninstall uwsgi
sudo apt-get install libpcre3 libpcre3-dev
pip install uwsgi