Python之Flask项目部署(Linux)-Gunicorn + Supervisor与Gunicorn + Systemd部署

张开发
2026/4/20 14:26:00 15 分钟阅读

分享文章

Python之Flask项目部署(Linux)-Gunicorn + Supervisor与Gunicorn + Systemd部署
在生产环境中部署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内容fromflaskimportFlask appFlask(__name__)app.route(/)defhello():returnHello, Gunicorn!if__name____main__:app.run()环境要求Linux操作系统本文以Ubuntu 22.04为例Python 3.8已创建虚拟环境并安装依赖pip install flask gunicorn验证Gunicorn能否手动启动cd/path/to/yourappsourcevenv/bin/activate gunicorn--workers3--bind0.0.0.0:8000 app:app如果访问http://你的服务器IP:8000能看到输出说明Gunicorn配置正确。接下来我们将使用进程管理工具来管理它。一、使用 Supervisor 部署Supervisor是一个用Python编写的进程管理工具可以监控和控制类Unix系统上的进程提供Web界面和命令行工具。1. 安装 Supervisorsudoaptupdatesudoaptinstallsupervisor安装后自动启动管理配置文件位于/etc/supervisor/conf.d/。2. 创建 Supervisor 配置文件新建配置文件/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 userwww-data # 运行进程的用户建议非root autostarttrue # 随supervisor启动而启动 autorestarttrue # 进程意外退出时自动重启 redirect_stderrtrue # 将stderr重定向到stdout stdout_logfile/var/log/flask_app/gunicorn.log stdout_logfile_maxbytes50MB stdout_logfile_backups10 environmentPATH/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路径。3. 加载配置并启动# 重新读取配置文件sudosupervisorctl reread# 更新配置添加新程序或修改sudosupervisorctl update# 启动程序sudosupervisorctl start flask_app# 查看状态sudosupervisorctl status如果状态显示RUNNING说明部署成功。4. 设置 Supervisor 开机自启Supervisor本身作为系统服务默认已经配置开机自启通过systemd管理。如果没有可以执行sudosystemctlenablesupervisorsudosystemctl start supervisor5. 常用 Supervisor 命令sudosupervisorctl status# 查看所有进程状态sudosupervisorctl restart flask_app# 重启指定程序sudosupervisorctl stop flask_app# 停止sudosupervisorctltailflask_app# 查看实时日志sudosupervisorctltailflask_app stderr二、使用 Systemd 部署Systemd 是现代Linux发行版默认的 init 系统可以管理用户和系统服务。用它来管理Gunicorn更“原生”。1. 创建 Systemd Service 文件新建文件/etc/systemd/system/flask_app.service[Unit] DescriptionGunicorn instance to serve Flask app Afternetwork.target [Service] Userwww-data Groupwww-data WorkingDirectory/path/to/yourapp EnvironmentPATH/path/to/yourapp/venv/bin EnvironmentFLASK_ENVproduction ExecStart/path/to/yourapp/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 app:app Restartalways RestartSec10 StandardOutputjournal StandardErrorjournal SyslogIdentifierflask_app [Install] WantedBymulti-user.target参数说明Afternetwork.target保证网络启动后再启动服务。Environment可以设置多个环境变量例如PATH、FLASK_ENV等。Restartalways无论退出码为何都自动重启。StandardOutputjournal日志输出到systemd journal可以用journalctl查看。2. 启动并启用服务# 重新加载systemd配置sudosystemctl daemon-reload# 启动服务sudosystemctl start flask_app# 设置开机自启sudosystemctlenableflask_app# 查看状态sudosystemctl status flask_app3. 常用 Systemd 命令sudosystemctl status flask_app# 查看状态和最近日志sudosystemctl restart flask_app# 重启sudosystemctl stop flask_app# 停止sudosystemctlenableflask_app# 开机自启sudosystemctl disable flask_app# 取消开机自启sudojournalctl-uflask_app-f# 实时查看服务日志三、两种方式的异同对比特性SupervisorSystemd原生性第三方工具需要单独安装Linux系统自带无需安装配置语法INI风格[program:name]类似INI[Service]等分段进程管理能力管理任意命令行进程管理系统服务功能更强大依赖关系、资源限制等用户权限通常以root运行Supervisor再切换用户执行子进程直接以指定User运行安全性好日志管理可配置日志文件轮转、大小限制默认输出到journald也可重定向到文件Web界面可选内置Web界面需配置无原生Web界面开机自启依赖systemd管理supervisor服务直接通过systemd enable进程监控粒度支持进程组、事件监听等支持目标单元、依赖链、失败自动恢复命令易用性supervisorctl命令行支持交互式systemctl更标准集成度高适用场景传统方式适合管理多个应用如旧系统现代Linux发行版首选管理所有系统服务相同点都能保证Gunicorn进程在崩溃后自动重启。都支持开机自启。都可以设置运行用户避免root风险。都提供基本的进程状态查询和日志查看。不同点重点集成度Systemd已深度集成到Linux内核和用户空间可以管理资源限制cgroup、socket激活、定时器等。Supervisor更轻量但功能较少。配置变更Systemd修改service文件后需执行systemctl daemon-reloadSupervisor修改配置文件后需supervisorctl reread update。日志Systemd默认使用journal适合集中日志管理Supervisor直接写文件适合传统运维习惯。学习曲线Systemd配置稍复杂但现代Linux管理员必须掌握Supervisor配置更简单适合不熟悉Systemd的开发者。四、修改后如何重新部署无论是修改了Flask代码还是修改了Gunicorn的启动参数如workers数量、bind地址都需要让进程管理工具重新启动Gunicorn进程。对于 Supervisor1. 仅修改代码未改Supervisor配置直接重启程序即可sudosupervisorctl restart flask_app这种方式会强制杀死旧进程并启动新进程会导致数秒的服务中断。如果需要优雅重启不丢失正在处理的请求可以发送HUP信号给Gunicorn主进程# 先获取Gunicorn主进程PID通过ps aux | grep gunicornsudokill-HUP主进程PID但Supervisor的重启命令不包含这个机制因此生产环境中建议使用Systemd的ExecReload或自己写脚本。2. 修改了 Supervisor 配置文件sudosupervisorctl reread# 读取所有配置变更sudosupervisorctl update# 应用变更会自动重启受影响的程序# 或者显式重启sudosupervisorctl restart flask_app对于 Systemd1. 仅修改代码重启服务sudosystemctl restart flask_app同样这会中断服务。更优雅的方式是向Gunicorn主进程发送HUP信号sudosystemctlkill-sHUP flask_app这会让Gunicorn重新加载应用代码而不中断连接worker进程逐个替换。注意如果修改了依赖或模块导入有变化可能需要完全重启。2. 修改了 Systemd service 文件sudosystemctl daemon-reload# 重新加载service文件sudosystemctl restart flask_app# 重启服务使新参数生效通用建议优雅重启的最佳实践对于生产环境建议在Gunicorn配置中添加--reload选项不推荐因为--reload会监控文件变化自动重启但可能消耗额外资源且不可控。更常用的做法是使用Gunicorn的--graceful-timeout和--timeout参数控制worker替换过程。配合负载均衡如Nginx实现蓝绿部署或滚动更新从上游摘除节点后再重启。简单场景下直接restart短暂中断1秒可以接受若要求更高可用性请使用kill -HUP。五、总结部署方式优点缺点Supervisor配置简单易上手支持Web界面适合管理多个非系统级进程额外依赖日志轮转需手动配置不是系统原生组件Systemd原生集成功能强大cgroup、socket激活等日志管理方便journalctl系统标准配置稍复杂在不同发行版间有细微差异但可接受推荐选择如果你的操作系统是较新的Linux发行版Ubuntu 16.04CentOS 7首选 Systemd。它是未来标准无需额外安装运维命令统一。如果你需要管理大量非系统级应用如多个Flask项目、Celery worker等且习惯了Supervisor的交互式命令行和Web监控可以使用Supervisor。但注意在Systemd系统中运行Supervisor实际上多了一层抽象。无论哪种方式请确保Gunicorn的worker数量适中建议(2*CPU核心数)1。使用Nginx等反向代理处理静态文件和负载均衡。日志有轮转策略避免磁盘占满。通过本文的详细步骤你应该能够轻松地将Flask项目部署到生产环境并理解两种主流进程管理方式的异同。根据你的团队习惯和基础设施选择合适的方案即可。

更多文章