Django3.0+supervisor+uvicorn+nginx进行线上部署
开门见山的说
最近一个项目使用了django3.0,那么没有道理不用一下asgi异步特性来玩一玩,部署的时候花费了一些力气,故留个笔记
uvicorn的使用
uvicorn采用了uvloop 用Cython改写了python里面asyncio的时间循环, 将asyncio的效率提高了4倍以上
安装
pip3 install uvicorn
本地跑一下项目试一试
uvicorn myproject.asgi:application
此时出现
表示项目正常运行
其它的参数请参照文档:
https://www.uvicorn.org/settings/
进程管理
用uvicorn部署了之后, 极高的提升了性能 但是在进程管理上就很麻烦
首先生产版本没有提供一个快速重启的接口 也没有优雅结束的功能
如果要结束服务,(特别是服务通过nohup等命令后台运行之后) 只能通过 ps -ef | grep uvicorn 查到进程id 然后通过 kill -9 process_id 杀死进程
那么supervisor就应运而生了. 这是一个进程管理系统, 可以把uvicorn运行成为它的子进程 从而进行管理
安装
yum install supervisor
测试是否安装成功
echo_supervisord_conf
然后会在/etc/supervisord.conf生成一个配置文件. 配置文件里曼有一行
[include]
files = supervisord.d/*.ini
也就是说在/etc/supervisord.d/里面的ini文件都会被包含进去
为了方便管理, 每一个应用最好都创建一个ini文件 放在/etc/supervisord.d/里面
vim /etc/supervisord.d/userSystem.ini
[fcgi-program:uvicorn]
socket=tcp://localhost:8000
directory=/usr/python_test/userSystem/
command=uvicorn --fd 0 userSystem.asgi:application
numprocs=4
process_name=uvicorn-%(process_num)d
stdout_logfile=/home/log/test.log
stdout_logfile_maxbytes=20MB
socket为对外暴露的接口 可以是unix 也可以是一个网络端口 端口的形式可以见官方文档
command为执行命令
directory为项目路径
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
当出现以下提示时 代表已经启动完成
nginx反向代理
直接上配置文件把
server {
listen 80;
server_name localhost
charset UTF-8;
access_log /home/log/test_nginx_access.log;
error_log /home/log/test_nginx_error.log;
client_max_body_size 75M;
location / {
proxy_pass http://127.0.0.1:8000;
}
}
然后重启nginx就完事了
nginx -s reload
结束
按照以上的步骤,能够部署号一个django3.0项目,性能高效,方便管理
假如出现错误
error: <class 'socket.error'>, [Errno 2] No such file or directory: file: <string> line: 1
后面找了很久,终于找到了解决问题的方法。执行前,请先确认supervisord.conf配置文件所在路径:
sudo supervisord -c /etc/supervisord.conf
sudo supervisorctl -c /etc/supervisord.conf