· 技术教程  · 11 min read

Python Web 应用终极部署教程:Gunicorn + PM2 持久化与生产级部署

深入解析如何使用 Gunicorn 和 PM2 将 Python Web 应用部署到生产环境,实现高性能、高可用的服务架构。

深入解析如何使用 Gunicorn 和 PM2 将 Python Web 应用部署到生产环境,实现高性能、高可用的服务架构。

当我们用 python app.py 运行 Flask 应用时,使用的是 Flask 自带的开发服务器。虽然在开发阶段很方便,但在生产环境中却存在致命的缺陷。本教程将详细介绍如何使用 Gunicorn 和 PM2 构建一套专业的 Python Web 应用部署方案。

一、为什么需要 Gunicorn 和 PM2?

开发服务器的问题

当我们用 python app.py 运行 Flask 应用时,使用的是 Flask 自带的开发服务器。它存在以下问题:

  1. 性能低下:单线程,无法处理并发请求,不适合生产环境
  2. 不稳定:遇到错误容易崩溃,且无法自动恢复
  3. 管理不便:关闭终端后进程就结束了,无法在后台持久运行

解决方案

为了解决这些问题,我们引入两个关键工具:

Gunicorn (Green Unicorn)

  • 角色:一个专业的 WSGI HTTP 服务器,取代 Flask 的开发服务器
  • 作用:负责接收来自反向代理(如 Nginx)的 HTTP 请求,并高效地将请求分发给 Python 应用的多个工作进程(workers)来处理,从而实现并发和高性能

PM2 (Process Manager 2)

  • 角色:一个全能的进程管理器
  • 作用:负责在后台运行和监控 Gunicorn 进程。如果 Gunicorn 或应用崩溃了,PM2 会立即自动重启它。同时,它还提供了日志管理、性能监控、开机自启动等强大的运维功能

部署架构

我们的部署架构将是这样的:

外部请求 -> Nginx (反向代理) -> PM2 (管理 Gunicorn) -> Gunicorn (运行应用) -> 你的 Python 应用

本教程聚焦于 Gunicorn 和 PM2 的结合,Nginx 部分可参考之前的教程

二、准备工作

在开始之前,请确保:

  1. Python 应用:确保你的 Flask 或 Django 应用在开发环境中可以正常运行
  2. 服务器:一台已经配置好基础环境的 Linux 服务器
  3. PM2 已安装:确保你已经通过 npm install -g pm2 全局安装了 PM2

三、安装并配置 Gunicorn

步骤 1:安装 Gunicorn

在你的项目环境中安装 Gunicorn。推荐在虚拟环境(如 venv)中操作,以保持项目依赖的隔离。

  1. 进入你的项目目录
cd /path/to/your/project
  1. (可选,但推荐)创建并激活虚拟环境
python3 -m venv venv
source venv/bin/activate
  1. 安装 Gunicorn 和你的项目依赖
pip install gunicorn
pip install -r requirements.txt  # 安装项目其他依赖

步骤 2:测试 Gunicorn 能否启动你的应用

这是关键的一步,确保 Gunicorn 能找到并运行你的应用实例。

对于 Flask 应用

假设你的启动文件是 app.py,并且里面的 Flask 实例变量名为 app(即 app = Flask(__name__))。

启动命令的格式是:gunicorn <模块名>:<实例名>

# -w: workers,工作进程数,推荐为 2 * CPU核心数 + 1
# -b: bind,绑定监听的地址和端口。在生产中,通常绑定在本地回环地址
gunicorn --workers 4 --bind 127.0.0.1:8000 app:app

对于 Django 应用

假设你的项目名为 myproject,Django 会自动生成一个 myproject/wsgi.py 文件,里面的 WSGI 应用实例名叫 application

启动命令的格式是:gunicorn <项目名>.wsgi:application

gunicorn --workers 4 --bind 127.0.0.1:8000 myproject.wsgi:application

执行上述命令后,如果终端没有报错,并显示 Gunicorn 正在监听,说明配置正确。按 Ctrl + C 停止它,我们接下来让 PM2 来接管。

四、使用 PM2 持久化 Gunicorn 进程

现在,我们让 PM2 成为 Gunicorn 的”守护神”,在后台运行它,并赋予它”不死之身”。

步骤 1:用 PM2 启动 Gunicorn

我们将刚才手动执行的 Gunicorn 命令,作为参数传给 pm2 start

# 语法: pm2 start "<gunicorn_command>" --name <app_name> --interpreter <python_path>

# 对于 Flask 应用
pm2 start "gunicorn --workers 4 --bind 127.0.0.1:8000 app:app" --name my-flask-app

# 对于 Django 应用
pm2 start "gunicorn --workers 4 --bind 127.0.0.1:8000 myproject.wsgi:application" --name my-django-app

参数说明

  • "gunicorn ...": 注意要用引号把整个 Gunicorn 命令包起来,这样 PM2 才会把它当作一个整体来执行
  • --name <app_name>: 给 PM2 进程起一个清晰的名字,方便管理
  • --interpreter <python_path> (可选): 如果你使用的是虚拟环境,为了确保 PM2 使用正确的 Python 解释器,最好明确指定

使用虚拟环境的完整示例

  1. 首先,在激活的虚拟环境下,用 which python 找到解释器的绝对路径(例如 /path/to/your/project/venv/bin/python
  2. 然后,在 PM2 命令中加入 --interpreter 参数:
pm2 start "gunicorn --workers 4 --bind 127.0.0.1:8000 app:app" --name my-flask-app --interpreter /path/to/your/project/venv/bin/python

步骤 2:管理和监控

现在,你的 Python 应用已经由 Gunicorn 驱动,并被 PM2 在后台持久化运行了。你可以使用所有熟悉的 PM2 命令来管理它:

  • 查看状态: pm2 listpm2 ls
  • 查看实时日志: pm2 logs my-flask-app
  • 重启应用 (零停机时间): pm2 restart my-flask-app
  • 查看性能监控: pm2 monit my-flask-app

步骤 3:配置 PM2 开机自启动

这是实现无人值守运维的最后一步。

  1. 生成启动脚本:
pm2 startup
  1. 执行 PM2 提示的 sudo 命令: 复制并执行 PM2 生成的那一行命令,以创建系统服务。

  2. 保存当前的应用列表:

pm2 save

这个命令会把你当前正在运行的所有应用(包括这个新的 Python 应用)都保存到启动列表中。

现在,即使服务器重启,PM2 也会自动启动,并根据保存的列表恢复 Gunicorn 进程,你的 Python 应用也会随之恢复服务。

五、使用配置文件(Ecosystem File)进行高级管理

当你的启动命令越来越复杂,或者需要配置更多高级选项时,把所有配置写在一个 ecosystem.config.js 文件中是更好的选择。

创建配置文件

  1. 在你的项目根目录创建一个 ecosystem.config.js 文件

  2. 编辑文件内容

// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'my-flask-app', // 应用名称
    script: 'gunicorn',    // 要执行的脚本,这里是 gunicorn
    args: '--workers 4 --bind 127.0.0.1:8000 app:app', // 传递给 gunicorn 的参数
    interpreter: '/path/to/your/project/venv/bin/python', // 虚拟环境的 Python 解释器
    cwd: '/path/to/your/project', // 应用的工作目录
    watch: false, // 是否监控文件变动重启,生产环境建议关闭
    env: {
      'NODE_ENV': 'production', // 环境变量
      'DB_HOST': 'localhost',
    }
  }]
};

使用配置文件启动应用

# 先删除旧的进程(如果存在)
pm2 delete my-flask-app

# 使用配置文件启动
pm2 start ecosystem.config.js

使用配置文件的好处是,所有配置一目了然,便于版本控制和团队协作。

六、高级配置和优化

Gunicorn 性能调优

Worker 数量配置

# 推荐公式:2 * CPU核心数 + 1
# 查看 CPU 核心数
nproc

# 设置 worker 数量
gunicorn --workers 4 --bind 127.0.0.1:8000 app:app

Worker 类型选择

# 默认同步 worker(适合 CPU 密集型应用)
gunicorn --workers 4 --worker-class sync app:app

# 异步 worker(适合 I/O 密集型应用)
gunicorn --workers 4 --worker-class gevent app:app

# 异步 worker with eventlet
gunicorn --workers 4 --worker-class eventlet app:app

PM2 高级配置

内存限制和自动重启

module.exports = {
  apps: [{
    name: 'my-flask-app',
    script: 'gunicorn',
    args: '--workers 4 --bind 127.0.0.1:8000 app:app',
    max_memory_restart: '1G', // 内存超过 1G 时自动重启
    min_uptime: '10s', // 最小运行时间
    max_restarts: 10, // 最大重启次数
    restart_delay: 4000, // 重启延迟
  }]
};

七、监控和日志管理

实时监控

# 查看所有应用状态
pm2 list

# 实时监控资源使用情况
pm2 monit

# 查看特定应用的详细信息
pm2 show my-flask-app

日志管理

# 查看实时日志
pm2 logs my-flask-app

# 查看错误日志
pm2 logs my-flask-app --err

# 清空日志
pm2 flush

# 重新加载日志
pm2 reloadLogs

八、故障排除

常见问题及解决方案

1. 应用无法启动

# 检查 PM2 状态
pm2 list

# 查看详细错误信息
pm2 logs my-flask-app --lines 50

2. 端口冲突

# 检查端口占用
netstat -tlnp | grep :8000

# 或使用 ss 命令
ss -tlnp | grep :8000

3. 虚拟环境问题

# 确认 Python 解释器路径
which python

# 在配置文件中明确指定解释器
interpreter: '/path/to/venv/bin/python'

总结

通过 Gunicorn + PM2 的组合,你为你的 Python Web 应用搭建了一套健壮、高性能、高可用的生产环境部署方案:

  • Gunicorn 负责高效地运行你的应用代码,提供并发处理能力
  • PM2 负责在后台守护 Gunicorn 进程,提供持久化、自动重启和便捷的管理功能

这套方案不仅解决了开发服务器的性能和稳定性问题,还提供了完整的运维管理功能,让你的 Python Web 应用能够在生产环境中稳定、高效地运行。

配合 Nginx 反向代理和适当的监控系统,你就拥有了一套完整的企业级 Python Web 应用部署架构。

Back to Blog

Related Posts

View All Posts »