ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
虽然 Flask 内置了服务器,其轻便且易于使用,但是 **Flask 的内建服务器不适用于生产**,也不能很好 的扩展。 ## 独立 WSGI 容器 - Gunicorn Gunicorn (绿色独角兽) 是一个 Python WSGI UNIX 的 HTTP 服务器。这是一个 pre-fork worker 的模型,从 Ruby 的独角兽([Unicorn](http://www.oschina.net/p/unicorn))项目移植。该 Gunicorn 服务器大致与各种 Web 框架兼容,实现非常简单,轻量级的资源消耗。Gunicorn 直接用命令启动,不需要编写配置文件,相对 uWSGI 要容易很多。 ### 安装 gunicorn ``` (.venv) root@airvip:~/python_app/flask-demo# pip install gunicorn ``` 安装成功后,通过命令行的方式可以查看如何使用 gunicorn ``` (.venv) root@airvip:~/python_app/flask-demo# gunicorn -h usage: gunicorn [OPTIONS] [APP_MODULE] optional arguments: -h, --help show this help message and exit -v, --version show program's version number and exit ``` 运行我们的项目 ``` (.venv) root@airvip:~/python_app/flask-demo# gunicorn -w 4 -b 127.0.0.1:8889 manage:app [2021-01-12 07:29:33 +0000] [22184] [INFO] Starting gunicorn 20.0.4 [2021-01-12 07:29:33 +0000] [22184] [INFO] Listening at: http://127.0.0.1:8889 (22184) [2021-01-12 07:29:33 +0000] [22184] [INFO] Using worker: sync [2021-01-12 07:29:33 +0000] [22187] [INFO] Booting worker with pid: 22187 [2021-01-12 07:29:33 +0000] [22188] [INFO] Booting worker with pid: 22188 [2021-01-12 07:29:33 +0000] [22189] [INFO] Booting worker with pid: 22189 [2021-01-12 07:29:33 +0000] [22190] [INFO] Booting worker with pid: 22190 # gunicorn 记录日志 gunicorn -w 4 -b 127.0.0.1:8889 manage:app --access-logfile /root/python_app/flask-demo/logs/access.log --error-logfile /root/python_app/logs/flask-demo/error.log ``` 测试 ``` root@airvip:~# curl 127.0.0.1:8889 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="/static/css/style.css"> <title>前后端分离静态页面</title> </head> <body> * 前后端分离的静态 HTML </body> </html> ``` 传送门:[Flask 部署方式更多使用技巧](https://dormousehole.readthedocs.io/en/latest/deploying/index.html#deployment) ## 进程管理工具 supervisor Supervisor 是一个 Python 开发的通用的进程管理程序,可以管理和监控 Linux 上面的进程,能将一个普通的命令行进程变为后台 daemon,并监控进程状态,异常退出时能自动重启。 ### 安装 supervisor ``` root@airvip:~# apt-get install supervisor ``` supervisor 是一个 Python 开发的,当然也可以使用 pip 安装。 ### 配置 ``` root@airvip:/etc/supervisor/conf.d# vim flask_demo.conf ``` 内容如下 ``` [group:flask_demo] ; programs=flask-demo-app ,flask-demo-celery programs=flask-demo-app ; [program:xx] 被管理的进程配置参数,xx 是进程的名称 [program:flask-demo-app] ; directory 脚本目录 directory=/root/python_app/flask-demo ; command 执行的命令 command=/root/python_app/flask-demo/scripts/manage.sh ; autostart 在supervisord启动的时候也自动启动 autostart=true ; startsecs 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒 startsecs=10 ; autorestart 程序退出后自动重启,可选值:[unexpected,true,false],默认为 unexpected,表示进程意外杀死后才重启 autorestart=true ; startretries 启动失败自动重试次数,默认是3 startretries=3 ; user 用哪个用户启动进程,默认是root user=root ; priority 进程启动优先级,默认999,值小的优先启动 priority=999 ; redirect_stderr 改为 true 则把 stderr 重定向到 stdout,默认 false redirect_stderr=true ; stdout_logfile_maxbytes 日志文件大小,默认 50MB stdout_logfile_maxbytes=50MB ; stdout_logfile_backups 日志文件备份数,默认是 10 stdout_logfile_backups=10 ; stdout_logfile 需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件) stdout_logfile=/mnt/logs/xx_stdout.log stderr_logfile=/mnt/logs/xx_stderr.log loglevel=info stopsignal=KILL ; stopasgroup 默认为 false,进程被杀死时,是否向这个进程组发送 stop 信号,包括子进程 stopasgroup=true ; killasgroup 默认为 false,向进程组发送 kill 信号,包括子进程 killasgroup=true ``` 在 `/root/python_app/flask-demo/scripts/` 目录下新建 `manage.sh `,内容如下 ``` #!/bin/bash source ~/.bashrc export FLASK_ENV=production cd /root/python_app/flask-demo/ source .venv/bin/activate exec gunicorn -b 0.0.0.0:8889 --access-logfile /root/python_app/flask-demo/logs/access.log --error-logfile /root/python_app/flask-demo/logs/error.log manage:app ``` 给 `manage.sh` 脚本可执行权限 ``` (.venv) root@airvip:~/python_app/flask-demo/scripts# chmod +x manage.sh ``` 查看 ``` # 查看 supervisor 是否已启动 root@airvip:/etc/supervisor/conf.d# ps -aux | grep supervisor root 11028 0.0 0.0 13136 1104 pts/2 S+ 09:22 0:00 grep --color=auto supervisor root 27948 0.0 1.0 65548 21372 ? Ss 07:59 0:01 /usr/bin/python /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf root@airvip:~# systemctl status supervisor root@airvip:~# systemctl start supervisor root@airvip:~# systemctl stop supervisor ``` ### supervisorctl supervisor 已经启动,我们可以利用 supervisorctl 来管理 ``` root@airvip:/etc/supervisor/conf.d# supervisorctl supervisor> update flask_demo: added process group supervisor> status flask_demo:flask-demo-app RUNNING pid 19110, uptime 0:00:19 ``` ### supervisorctl 常用命令 ``` supervisor> status # 查看程序状态 supervisor> start flask-im # 启动 flask-im 单一程序 supervisor> stop flask-demo:* # 关闭 flask-demo 组程序 supervisor> start flask-demo:* # 启动 flask-demo 组程序 supervisor> restart flask-demo:* # 重新启动 flask-demo 组程序 supervisor> update # 重启配置文件修改过的程序 supervisor> reload # 重新启动配置文件中的所有程序 supervisor> exit # 退出 ```