1、WSGI協議
Web框架致力于如何生成HTML代碼,而Web服務器用于處理和響應HTTP請求。Web框架和Web服務器之間的通信,需要一套雙方都遵守的接口協議。WSGI協議就是用來統一這兩者的接口的。
2、WSGI容器
常用的WSGI容器有Gunicorn和uWSGI,但Gunicorn直接用命令啟動,不需要編寫配置文件,相對uWSGI要容易很多
3、gunicorn介紹
gunicorn是一個python Wsgi http server,只支持在Unix系統上運行,來源于Ruby的unicorn項目。Gunicorn使用prefork master-worker模型(在gunicorn中,master被稱為arbiter),能夠與各種wsgi web框架協作。
為啥要用 gunicorn
Flask 是一個 Platform,他本身并不包括 Web Server,為了使用方便,Flask 內置了一個 Werkzeug wsgi server 但是這個 server 并不高效。 如果是工業部署的話, 就需要用 Gunicorn 去替代掉這個內置的 Wsgi Server.
簡單說下幾種部署方式
- Flask 內置 WebServer + Flask App = 弱雞版本的 Server, 單進程(單 worker) / 失敗掛掉 / 不易 Scale
- Gunicorn + Flask App = 多進程(多 worker) / 多線程 / 失敗自動幫你重啟 Worker / 可簡單Scale
- 多 Nginx + 多 Gunicorn + Flask App = 小型多實例 Web 應用,一般也會給 gunicorn 掛 supervisor
在生產環境中:一般都是請求的走向都是 Nginx->gunicorn->flask/django app
4、gunicorn安裝
gunicorn安裝非常簡單,使用命令pip install gunicorn即可。一般使用它,主要是為使用其異步的worker模型,還需要安裝對應的異步模塊。
$ pip install gunicorn
$ pip install greenlet # 使用異步必須安裝
$ pip install eventlet # 使用eventlet workers
$ pip install gevent # 使用gevent workers
5、gunicorn使用
這里使用gunicorn來部署一個flask項目舉例,此處flask框架的使用不過多闡述,不是本文的重點。
如下例子,保存為app.py
from flask import Flask
app = Flask(__name__)@app.route("/")
def hello():return "Hello World!"
gunicorn通常使用的參數如下:
-c CONFIG, --config=CONFIG # 設定配置文件。
-b BIND, --bind=BIND # 設定服務需要綁定的端口。建議使用HOST:PORT。
-w WORKERS, --workers=WORKERS # 設置工作進程數。建議服務器每一個核心可以設置2-4個。
-k MODULE # 選定異步工作方式使用的模塊。
在shell中輸入你的啟動配置,比如:
gunicorn -w 3 -b 127.0.0.1:8080 app:app
# 此處app:app中,第一個app為flask項目實例所在的包,第二個app為生成的flask項目實例
這樣運行正常就可以啟動服務器了。
如果要通過網絡訪問,則需要綁定不同的地址(也可以同時設置監聽端口),設置0.0.0.0可以監聽到所有ip的請求:
gunicorn -b 0.0.0.0:8080 app:app
6、綁定端口
linux通常會禁止綁定使用1024以下的端口,除非在root用戶權限。很多人在使用gunicorn時試圖將其綁定到80或者443端口,發現無效。如果想綁定到這些端口,常見的有如下的幾種方法:
- 使用Nginx代理轉發。
- sudo啟動gunicorn。
- 安裝額外的程序。
7、結束gunicorn服務進程
使用ps -ef | grep gunicorn命令找出gunicorn所有進程。
# ps -ef | grep gunicorn
root 16843 23035 0 Oct14 ? 00:00:02 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app
root 22445 23035 0 Oct04 ? 00:00:15 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app
root 22581 23035 0 Oct11 ? 00:00:05 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app
root 23035 1 0 Sep27 ? 00:04:11 /root/Envs/myflask/bin/python3.6 /root/Envs/myflask/bin/gunicorn -w 3 -b 172.17.0.12:80 app:app
然后使用 kill -9 進程ID 命令來殺掉進程,注意,我們找到主進程殺掉即可,子進程會隨之結束,在上例中,主進程號為23035.
# kill -9 23035
# ps -ef | grep gunicorn
殺掉進程后,稍等幾秒,再使用ps -ef | grep gunicorn查看,發現gunicorn服務進程已全部殺掉。
8、配置文件
通過gunicorn -h可以看到gunicorn有非常多的配置項,因此通常會寫成一個配置文件來進行配置。
比如gunicorn.conf文件
# gunicorn.confbind = "0.0.0.0:5000"
workers = 4
backlog = 2048
pidfile = "log/gunicorn.pid"
accesslog = "log/access.log"
errorlog = "log/debug.log"
timeout = 600
# debug=False生產環境不用這個配置項,但調試的時候debug=True還是挺好用的。而且,開啟debug項后,在啟動gunicorn的時候可以看到所有可配置項的配置
debug=False
capture_output = True
注意上面log項,如果需要將這些log文件統一放到log文件夾下,事先要先建好,不然運行時會報錯。
運行代碼為:
gunicorn --config gunicorn.conf main:app