在生产环境中部署Flask应用时,Flask自带的开发服务器(app.run())并不适合,因为它单进程、低性能且不稳定。我们需要一个高性能的WSGI服务器(如Gunicorn)和一个进程管理工具(如Supervisor或Systemd)来确保服务持续运行、自动重启和开机自启。
本文将详细讲解如何使用 Gunicorn + Supervisor 和 Gunicorn + Systemd 两种方式部署Flask项目,对比它们的异同,并说明代码或配置修改后如何重新部署。
假设你已经拥有一个基本的Flask项目,结构如下:
/path/to/yourapp/
├── app.py # 你的Flask应用入口
├── venv/ # Python虚拟环境(推荐)
└── requirements.txt
示例 app.py 内容:
from flask import Flask
app = Flask(__name__)
@app.route('/')
defhello():
return"Hello, Gunicorn!"
if __name__ =='__main__':
app.run()
环境要求:
pip install flask gunicorn验证Gunicorn能否手动启动:
cd /path/to/yourapp
source venv/bin/activate
gunicorn --workers3--bind0.0.0.0:8000 app:app
如果访问 http://你的服务器IP:8000 能看到输出,说明Gunicorn配置正确。接下来我们将使用进程管理工具来管理它。
Supervisor是一个用Python编写的进程管理工具,可以监控和控制类Unix系统上的进程,提供Web界面和命令行工具。
sudoapt update
sudoaptinstall supervisor
安装后自动启动,管理配置文件位于 /etc/supervisor/conf.d/。
新建配置文件 /etc/supervisor/conf.d/flask_app.conf:
[program:flask_app]
command=/path/to/yourapp/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 app:app
directory=/path/to/yourapp
user=www-data # 运行进程的用户,建议非root
autostart=true # 随supervisor启动而启动
autorestart=true # 进程意外退出时自动重启
redirect_stderr=true # 将stderr重定向到stdout
stdout_logfile=/var/log/flask_app/gunicorn.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10
environment=PATH="/path/to/yourapp/venv/bin" # 可选,设置环境变量
注意:
将 /path/to/yourapp替换为你的实际项目路径。确保 user有权限访问项目目录和日志目录。可以先创建日志目录:sudo mkdir -p /var/log/flask_app && sudo chown www-data:www-data /var/log/flask_app如果虚拟环境路径不同,请调整 command中的gunicorn路径。
# 重新读取配置文件
sudo supervisorctl reread
# 更新配置(添加新程序或修改)
sudo supervisorctl update
# 启动程序
sudo supervisorctl start flask_app
# 查看状态
sudo supervisorctl status
如果状态显示 RUNNING,说明部署成功。
Supervisor本身作为系统服务,默认已经配置开机自启(通过systemd管理)。如果没有,可以执行:
sudo systemctl enable supervisor
sudo systemctl start supervisor
sudo supervisorctl status # 查看所有进程状态
sudo supervisorctl restart flask_app # 重启指定程序
sudo supervisorctl stop flask_app # 停止
sudo supervisorctl tail flask_app # 查看实时日志
sudo supervisorctl tail flask_app stderr
Systemd 是现代Linux发行版默认的 init 系统,可以管理用户和系统服务。用它来管理Gunicorn更“原生”。
新建文件 /etc/systemd/system/flask_app.service:
[Unit]
Description=Gunicorn instance to serve Flask app
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/yourapp
Environment="PATH=/path/to/yourapp/venv/bin"
Environment="FLASK_ENV=production"
ExecStart=/path/to/yourapp/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 app:app
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=flask_app
[Install]
WantedBy=multi-user.target
参数说明:
After=network.target:保证网络启动后再启动服务。 Environment:可以设置多个环境变量,例如PATH、FLASK_ENV等。 Restart=always:无论退出码为何,都自动重启。 StandardOutput=journal:日志输出到systemd journal,可以用 journalctl查看。
# 重新加载systemd配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start flask_app
# 设置开机自启
sudo systemctl enable flask_app
# 查看状态
sudo systemctl status flask_app
sudo systemctl status flask_app # 查看状态和最近日志
sudo systemctl restart flask_app # 重启
sudo systemctl stop flask_app # 停止
sudo systemctl enable flask_app # 开机自启
sudo systemctl disable flask_app # 取消开机自启
sudo journalctl -u flask_app -f# 实时查看服务日志
| 原生性 | ||
| 配置语法 | [program:name] | [Service]等分段 |
| 进程管理能力 | ||
| 用户权限 | ||
| 日志管理 | ||
| Web界面 | ||
| 开机自启 | ||
| 进程监控粒度 | ||
| 命令易用性 | supervisorctl | systemctl |
| 适用场景 |
相同点:
不同点(重点):
systemctl daemon-reload;Supervisor修改配置文件后需 supervisorctl reread && update。无论是修改了Flask代码,还是修改了Gunicorn的启动参数(如workers数量、bind地址),都需要让进程管理工具重新启动Gunicorn进程。
直接重启程序即可:
sudo supervisorctl restart flask_app
这种方式会强制杀死旧进程并启动新进程,会导致数秒的服务中断。如果需要优雅重启(不丢失正在处理的请求),可以发送HUP信号给Gunicorn主进程:
# 先获取Gunicorn主进程PID(通过ps aux | grep gunicorn)
sudokill-HUP<主进程PID>
但Supervisor的重启命令不包含这个机制,因此生产环境中建议使用Systemd的 ExecReload 或自己写脚本。
sudo supervisorctl reread # 读取所有配置变更
sudo supervisorctl update # 应用变更(会自动重启受影响的程序)
# 或者显式重启
sudo supervisorctl restart flask_app
重启服务:
sudo systemctl restart flask_app
同样,这会中断服务。更优雅的方式是向Gunicorn主进程发送HUP信号:
sudo systemctl kill-s HUP flask_app
这会让Gunicorn重新加载应用代码而不中断连接(worker进程逐个替换)。注意:如果修改了依赖或模块导入有变化,可能需要完全重启。
sudo systemctl daemon-reload # 重新加载service文件
sudo systemctl restart flask_app # 重启服务使新参数生效
对于生产环境,建议在Gunicorn配置中添加 --reload 选项?不推荐,因为 --reload 会监控文件变化自动重启,但可能消耗额外资源且不可控。更常用的做法是:
--graceful-timeout 和 --timeout 参数控制worker替换过程。简单场景下,直接 restart 短暂中断(<1秒)可以接受;若要求更高可用性,请使用 kill -HUP。
| Supervisor | ||
| Systemd |
推荐选择:
无论哪种方式,请确保:
(2*CPU核心数)+1)。通过本文的详细步骤,你应该能够轻松地将Flask项目部署到生产环境,并理解两种主流进程管理方式的异同。根据你的团队习惯和基础设施选择合适的方案即可。
CSDN地址:
https://blog.csdn.net/weixin_45146962/article/details/159989560?sharetype=blogdetail&sharerId=159989560&sharerefer=PC&sharesource=weixin_45146962&spm=1011.2480.3001.8118
欢迎关注公众号,感谢对文章的点赞分享喜欢,冉成未来会持续更新前后端开发技术、人工智能技术、IT相关的文章及学习经验、知识分享,未来虽然充满着不确定性,但我们可以不断提升自己,不断为未来做准备,让未来更好的自己成就更美好的未来。
Python基础系列 | Python之PyQt5基础知识(五)
Python基础系列 | Python之PyQt5基础知识(四)
Python基础系列 | Python之PyQt5基础知识(三)
Python基础系列 | Python之PyQt5基础知识(二)
Python基础系列 | Python之PyQt5基础知识(一)