Nginx+Gunicorn+Flask+Supervisor 部署 Python 服務的詳細教程!
雖然標題寫的是 Flask,但是下面這個教程不僅僅只適用於 Flask,還適用於其他Python web 框架,記得幫忙點贊!
眾所周知 Flask 是一個同步的框架,處理請求的時候是以單程式的方式,當同時訪問的人數過多時,Flask 服務就會出現阻塞的情況。
就像我們買火車票一樣,當買火車票的人多的時候,排隊的人就會很多,隊伍就會很長,相應的等待的時間會變得很長!
因此 Flask,Django,webpy 等框架自帶的 web server 效能都很差,只能用來做測試用途,線上釋出則需要選擇更高效能的 wsgi server 。這裡推薦的部署方式:nginx + gunicorn + flask + supervisor
其中每個服務代表的含義如下:
-
Nginx:高效能 Web 伺服器+負載均衡;
-
gunicorn:高效能 WSGI 伺服器;
-
gevent:把 Python 同步程式碼變成非同步協程的庫;
-
Supervisor:監控服務程式的工具;
這裡有張圖,能讓你有個更直觀的感受
Gunicorn
Gunicorn 可以指定多個工作程式,有多種工作模式可以供你選擇。預設是同步的 sync 工作模式,除此之外還有 gevent,tronado,gthread,gaiohttp 等。
這裡推薦 gevent,gevent 是一個基於 Greenlet 庫,利用 python 協程來實現,這樣你的 web 服務才能實現併發的功能!
之前有寫過關於 gunicorn 的一篇文章,詳細使用指南點選檢視!
Nginx
Nginx 實際上只能處理靜態資源請求,那麼對於動態請求怎麼做呢。這就需要用到 Nginx 的 upstream
模組對這些請求進行轉發,即反向代理。Nginx 在這裡主要是用來做負載均衡,同時它能快取一些動態內容
安裝 nginx
安裝命令如下:
sudo apt-get install nginx
複製程式碼
nginx 安裝完後,我們可以通過以下命令控制 nginx 的開啟和關閉
sudo /etc/init.d/nginx restart // 重啟sudo /etc/init.d/nginx start 開啟
sudo /etc/init.d/nginx stop 關閉
複製程式碼
配置 nginx
Nginx 配置檔案位於 /usr/local/nginx/conf/nginx.conf
server {
listen 8080; # 監聽8080埠,可以自行配置
server_name localhost; # 配置域名
# 動態請求轉發到 9600 埠(gunicorn):
location / {
proxy_pass http://127.0.0.1:9600;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 300;
proxy_send_timeout 300;
}
}
複製程式碼
修改完之後儲存,重啟 nginx.
Supervisor
安裝 supervisor
命令如下:
pip install supervisor
複製程式碼
初始化配置檔案:
echo_supervisord_conf > supervisor.conf
複製程式碼
修改配置檔案,在配置檔案最底部新增相應配置
[include] 自己的專案配置
[program:project]
directory = /home/jerry/Code/project ; 程式的啟動目錄
command = /home/jerry/.virtualenvs/parsing/bin/gunicorn -w 4 -worker-class gevent -bind 0.0.0.0:9600 app:app ; 啟動命令
numprocs=1 ; number of processes copies to start (def 1)
autostart = true ; 在 supervisord 啟動的時候也自動啟動
startsecs = 1 ; 啟動 1 秒後沒有異常退出,就當作已經正常啟動了
autorestart = true ; 程式異常退出後自動重啟
startretries = 3 ; 啟動失敗自動重試次數,預設是 3
user = root ; 用哪個使用者啟動
redirect_stderr = true ; 把 stderr 重定向到 stdout,預設 false
stdout_logfile_maxbytes = 20MB ; stdout 日誌檔案大小,預設 50MB
stdout_logfile_backups = 10 ; stdout 日誌檔案備份數
stdout_logfile=/home/jerry/Code/project/log/gunicorn.log ; log 日誌
stderr_logfile=/home/jerry/Code/project/log/gunicorn.error ; 錯誤日誌
複製程式碼
編輯完之後儲存,啟動 supervisor。這裡的啟動命令和在命令列用 gunicorn 啟動的命令是一致的,其中 -w 是指服務的程式數,詳細命令檢視我之前寫的那篇文章哈。
基本命令
通過配置檔案啟動 supervisor
supervisord -c supervisor.conf
複製程式碼
檢視 supervisor 的狀態
supervisorctl -c supervisor.conf status
複製程式碼
重新載入配置檔案,每次修改之後記得重新載入
supervisorctl -c supervisor.conf reload
複製程式碼
啟動指定/所有 supervisor 管理的程式程式
supervisorctl -c supervisor.conf start [all]|[appname]
複製程式碼
關閉指定/所有 supervisor管理的程式程式
supervisorctl -c supervisor.conf stop [all]|[appname]
複製程式碼
這時候通過 http://127.0.0.1:8080 就能訪問你的應用了! 想知道效果如何,可以自己測試一下,比如在程式碼中增加 sleep,或者自己動手寫個指令碼測試!