Flask 高並發部署方案詳細教程!

  • 2019 年 12 月 5 日
  • 筆記

前言

雖然標題寫的是 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 的一篇文章,詳細使用指南點擊查看!

一個高性能的web服務是如何搭建的?

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,或者自己動手寫個腳本測試!