需求分析:
需要在linux服務器上部署一個asgi應用(例如 Quart 一個類flask的異步網絡框架)
1.直接運行
# main.py from quart import Quart app = Quart(__name__) app.run(host='0.0.0.0', port=8080)
以上是一個簡單的quart應用
可以直接在命令行通過
python3 main.py
直接運行 以啟動服務
當然這種是肯定不行的 從小時候媽媽就教育我們 不要在生產環境直接運行python main.py
因此我們的第一個需求就出現了. 需要一個asgi網關接口(他是wsgi的擴展 支持websocket) ( Python Web Server Gateway Interface,WSGI)
2.采用uvicorn部署asgi應用
常用的asgi有Daphne Hypercorn 以及下文介紹的uvicorn.
uvicorn采用了uvloop 用Cython改寫了python里面asyncio的時間循環, 將asyncio的效率提高了4倍以上
不幸的是, uvicorn只可以運行在linux系統上.
部署指令也很簡單
pip3 install uvicorn
uvicorn --host 0.0.0.0 --port 8080 main:app
其他設置參數詳見
https://www.uvicorn.org/settings/
3.進程管理(pm2)
https://blog.csdn.net/qq_36938617/article/details/95679412
npm install pm2 -g
// x.json
{ "name": "wxgzh", "cwd": "/root/Envs/wx/gzh", "script": "/root/Envs/wx/bin/uvicorn --uds wx.sock main:app.asgi", "log_date_format": "YYYY-MM-DD HH:mm:ss Z", "error_file": "error.log", "out_file": "access.log", "cron_restart": "0 4 * * *", "pid_file": "wx.pid", "watch": false, "autorestart": true, }
pm2 start x.json
3.進程管理
用uvicorn部署了之后, 極高的提升了性能 但是在進程管理上就很麻煩
首先生產版本沒有提供一個快速重啟的接口 也沒有優雅結束的功能
如果要結束服務,(特別是服務通過nohup等命令后台運行之后) 只能通過 ps -ef | grep uvicorn 查到進程id 然后通過 kill -9 process_id 殺死進程
那么supervisor就應運而生了. 這是一個進程管理系統, 可以把uvicorn運行成為它的子進程 從而進行管理
安裝方法
yum install supervisor # centOS7
測試是否安裝成功
#測試是否安裝成功 echo_supervisord_conf
然后會在/etc/supervisord.conf生成一個配置文件. 配置文件里曼有一行
[include]
files = supervisord.d/*.ini
也就是說在/etc/supervisord.d/里面的ini文件都會被包含進去
為了方便管理, 每一個應用最好都創建一個ini文件 放在/etc/supervisord.d/里面
vim /etc/supervisord.d/app1.ini [fcgi-program:uvicorn] socket=unix:///root/Envs/wx/gzh/wx.sock command=/root/Envs/wx/bin/uvicorn --fd 0 main:app.asgi numprocs=4 directory=/root/Envs/wx/gzh process_name=uvicorn-%(process_num)d stdout_logfile=/root/Envs/wx/gzh/out.log stdout_logfile_maxbytes=0
socket為對外暴露的接口 可以是unix 也可以是一個網絡端口 端口的形式可以見官方文檔
command為執行命令. 這里我是在虛擬環境里面運行的, 所以用的是 /root/Envs/wx/bin/uvicorn
這里有一個坑. 就是后面的app內容(即本例中的 main:app.asgi) 不可以用絕對路徑. (踩坑踩了好久) 需要在下面配置 directory 然后用相對路徑的方式 寫出app的為止
這里app是我的一個類. 在這個類里面暴露了asgi 所以采用的寫法是 main:app.asgi
numprocs是處理器個數
process_name是處理進程的名稱
保存之后 用這個命令啟動
supervisorctl update #一定要先更新 supervisorctl start uvicorn:* supervisorctl stop uvicorn:* supervisorctl restart uvicorn:*
:*的作用是所有進程,. 其所有命令為:
start <name> Start a process start <gname>:* Start all processes in a group start <name> <name> Start multiple processes or groups start all Start all processes
當出現以下提示時 代表已經啟動完成
4.nginx反代
nginx反代有很多文章介紹了 這里就不贅述了. 直接proxy到剛才在supervisord里面暴露的sock即可.
server { listen 80; server_name wx.domain.com; location / { proxy_pass http://unix:/root/Envs/wx/gzh/wx.sock; } }
然后重新nginx就可以了
nginx -s reload
按照以上步驟, 通過uvicorn+supervisord+nginx完全部署好了一個asgi應用. 性能高效 方便管理.