使用 PM2 守护 Flask 应用:从安装到配置详解
使用 PM2 守护 Flask 应用:从安装到配置详解
dong4j简介
PM2 是一个功能强大的 Node.js 进程管理工具,不仅适用于 JavaScript 项目,也能很好地守护 Python 应用。本文将详细介绍如何在服务器上使用 PM2 来守护一个基于 Flask 的 Python 应用。
1. 安装环境
安装 Node.js
PM2 是基于 Node.js 的工具,因此需要先安装 Node.js 环境:
1 | sudo apt update && sudo apt install curl -y |
安装 PM2
使用 npm 全局安装 PM2:
1 | npm install pm2 -g |
验证安装是否成功:
1 | pm2 -v # 查看版本 |
2. 准备 Flask 应用
生成依赖文件
在 Python 项目中,通常会使用 requirements.txt
来管理依赖包。如果尚未生成该文件,可以通过以下命令创建:
1 | pip freeze > requirements.txt |
配置虚拟环境(可选但推荐)
为了保持项目的独立性,建议为 Flask 应用创建一个 Python 虚拟环境。
1 | python3 -m venv my_flask_env # 创建虚拟环境 |
激活后,在虚拟环境中安装项目依赖:
1 | pip install -r requirements.txt |
编写启动脚本
Flask 应用通常需要通过 gunicorn
或 uwsgi
来运行,以提高性能和并发处理能力。
假设你的 Flask 应用文件为 app.py
,以下是使用 gunicorn
启动的配置示例:
1 | # 安装 gunicorn |
你也可以为 gunicorn
配置一个参数文件(如 gunicorn_config.py
),以进一步优化性能:
1 | # gunicorn_config.py |
3. 使用 PM2 守护 Flask 应用
直接启动
你可以将 gunicorn
命令通过 PM2 管理:
1 | pm2 start gunicorn -c gunicorn_config.py wsgi:app --name=flask_app |
使用自定义脚本
为了更好地管理,可以编写一个启动脚本(如 start.sh
):
1 |
|
然后通过 PM2 管理该脚本:
1 | pm2 start start.sh --name=flask_app |
配置文件(可选)
你也可以为 PM2 编写一个 JSON 配置文件(如 ecosystem.config.js
),以便管理和部署多个应用。
1 | module.exports = { |
然后运行:
1 | pm2 start ecosystem.config.js |
4. PM2 命令列表
命令 | 描述 |
---|---|
pm2 start <app.js> [--name=<name>] | 启动应用 |
pm2 stop <app_name/id> | 停止应用 |
pm2 restart <app_name/id> | 重启应用 |
pm2 delete <app_name/id> | 删除应用 |
pm2 list | 列出所有应用 |
pm2 show <app_name/id> | 显示应用详细信息 |
pm2 info <app_name/id> | 显示应用信息(等同于 show) |
pm2 status | 显示 PM2 状态 |
pm2 logs | 显示所有应用日志 |
pm2 logs <app_name/id> | 显示指定应用日志 |
pm2 flush | 清空所有日志文件 |
pm2 reloadLogs | 重新加载日志 |
pm2 deploy | 部署应用 |
pm2 deploy <configuration_file> <environment> | 使用配置文件部署到指定环境 |
pm2 monit | 监控所有应用 |
pm2 cpu <app_name/id> | 显示应用 CPU 使用情况 |
pm2 memory <app_name/id> | 显示应用内存使用情况 |
pm2 startup | 生成启动脚本 |
pm2 save | 保存当前应用列表 |
pm2 resurrect | 恢复之前保存的应用列表 |
pm2 update | 更新 PM2 到最新版本 |
pm2 scale <app_name/id> <number_of_instances> | 扩展应用实例数量 |
pm2 gracefulReload <app_name/id> | 优雅重启应用 |
pm2 trigger <app_name/id> <action_name> | 触发自定义动作 |
pm2 set <key> <value> | 设置 PM2 配置项 |
pm2 unset <key> | 取消设置 PM2 配置项 |
pm2 help | 显示帮助信息 |
pm2 home | 打开 PM2 官网 |
pm2 plus | 打开 PM2 Plus 服务页面 |
pm2 module:list | 列出所有 PM2 模块 |
pm2 module:install <module_name> | 安装 PM2 模块 |
pm2 module:uninstall <module_name> | 卸载 PM2 模块 |
参数 | 描述 |
---|---|
--name | 设置应用的名称 |
--cwd | 指定启动应用时的工作目录 |
--watch | 监听文件变化,自动重启应用 |
--ignore-watch | 忽略监听的文件或目录 |
--max-memory-restart | 设置应用内存使用上限,超过后自动重启 |
--exec-path | 指定 Node.js 的执行路径 |
--instances | 设置应用实例的数量 |
--instance | 指定启动的实例编号 |
--env | 设置环境变量 |
--port | 指定应用的端口号 |
--cron | 设置定时重启任务 |
--interpreter | 指定解释器路径 |
--interpreter-args | 传递给解释器的参数 |
--output | 指定输出日志文件路径 |
--error | 指定错误日志文件路径 |
--pid | 指定 PID 文件路径 |
--log-date-format | 设置日志日期格式 |
--merge-logs | 合并日志文件 |
--no-daemon | 不以守护进程方式运行 |
--no-vizion | 禁用 vizion 版本控制 |
--no-autorestart | 禁用自动重启 |
--restart-delay | 设置重启延迟时间 |
--force | 强制重启或停止应用 |
--update-env | 更新环境变量 |
--only | 只启动指定的应用 |
--kill-timeout | 设置强制杀死进程的超时时间 |
--wait-ready | 等待应用准备好后再继续 |
--ready-delay | 设置等待准备好的延迟时间 |
--attach | attaching to application output |
--no-attach | do not attach to application output |
常见问题
目前使用 PM2 来管理了多种类型的服务, 比如 python, js, golan 等, 期间也遇到了一些问题, 这里做一下总结.
pm2 找不到
我一般都是在客户端上使用 shell 脚本通过 pm2 来管理服务, 所以会有下面这样的启动命令:
1 | ssh "$SSH_ALIAS" "pm2 list" |
上面的脚本执行会报下面的错误:
1 | zsh:1: command not found: pm2 |
当通过 SSH 远程执行命令时,系统会启动一个非交互式的 shell。在这种模式下,某些启动文件(如 .bashrc 或 .zshrc)可能不会被自动加载,导致环境变量(如 PATH)未被正确设置。因此,系统无法找到 pm2 命令。
所以正确的方式应该是:
1 | ssh "$SSH_ALIAS" "source ~/.nvm/nvm.sh && pm2 list" |
watch 问题
PM2 提供一个 watch 参数, 但文件发生变化时会重启服务, 但是在服务运行过程中可能会生成一些临时文件或改动文件, 这会导致服务重启, 这里我们可以设置 ignore_watch
参数来避免这种问题, 比如:
1 | module.exports = { |
这里排除了 node_modules
和 logs
目录的监控.
用户权限问题
我服务器上使用了普通用户安装的 Node.js 和 pm2, 但是某些服务需要使用 root 用户运行时, 需要修改启动命令:
1 | ssh "$REMOTE_SSH_ALIAS" "source /home/{username}/.nvm/nvm.sh && pm2 start $REMOTE_PATH/ecosystem.config.js" |
比如上面的服务使用 root 用户运行. 这样也会带来问题, 即在服务器上 root 用户使用 pm2 管理服务需要使用下面的命令:
1 | /home/{username}/.nvm/versions/node/{version}/bin/pm2 list |
而普通用户也无法通过 sudo pm2 xxx
管理服务, 所以最简单的方式就是使用 root 用户再安装一个 pm2, 简单粗暴往往是最好的方式 🤣.