目录
1. 为什么使用 ecosystem.config.js?
1.1 什么是 ecosystem.config.js?
ecosystem.config.js 是 PM2 的配置文件,用于定义和管理多个服务进程。
1.2 不用配置文件的问题
| 启动方式 | 问题 |
|---|---|
pm2 start npm -- ... |
命令复杂,容易写错 |
pm2 start app.js -- --args |
参数难以管理 |
| 多个服务分别启动 | 需要记多个命令,容易遗漏 |
1.3 使用配置文件的优势
| 优势 | 说明 |
|---|---|
| 集中管理 | 所有服务配置在一个文件 |
| 一键启动 | pm2 start ecosystem.config.js 启动所有服务 |
| 版本控制 | 配置可以提交到 Git,团队共享 |
| 环境变量 | 方便配置敏感信息 |
| 统一日志 | 日志路径统一管理 |
| 自动重启 | 崩溃自动恢复 |
1.4 潜在缺点
| 缺点 | 解决方案 |
|---|---|
| 敏感信息泄露 | 使用 .env 文件,不提交到 Git |
| 配置复杂 | 参考本文档 |
2. 配置示例与参数详解
2.1 实际配置示例
module.exports = {
apps: [
// MongoDB 数据库服务
{
name: 'mongodb',
script: '/usr/bin/mongod',
args: '--dbpath /data/gamedb --port 27017 --bind_ip 127.0.0.1 --logpath /data/gamedb/mongodb.log --logappend --systemLog.rotation.size 50000000',
cwd: '/',
instances: 1,
autorestart: true,
watch: false,
},
// 游戏服务器
{
name: 'game-server',
script: './build/gameServer.js',
cwd: '/home/prod/game_server',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production'
},
error_file: './logs/game-server-error.log',
out_file: './logs/game-server-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true
},
// 管理后台
{
name: 'game-admin',
script: './build/adminServer.js',
cwd: '/home/prod/game_server',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production'
},
error_file: './logs/game-admin-error.log',
out_file: './logs/game-admin-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true
}
]
};
2.2 参数详解
基础参数
| 参数 | 说明 | 示例值 |
|---|---|---|
name |
进程名称,用于标识 | game-server |
script |
启动脚本路径 | ./build/gameServer.js |
cwd |
工作目录 | /home/prod/game_server |
args |
启动参数(仅对脚本生效) | --port 27017 |
进程管理参数
| 参数 | 说明 | 示例值 |
|---|---|---|
instances |
启动实例数量 | 1 |
autorestart |
崩溃时自动重启 | true |
watch |
监听文件变化(生产环境必须 false) |
false |
max_memory_restart |
内存超过阈值自动重启 | '1G' |
环境变量参数
| 参数 | 说明 | 示例值 |
|---|---|---|
env |
环境变量对象 | { NODE_ENV: 'production' } |
NODE_ENV |
运行环境 | production / development |
注意:敏感信息(WX_APPID、WX_SECRET)不写入此文件,而是通过 .env 文件或命令行传入。
日志参数
| 参数 | 说明 | 示例值 |
|---|---|---|
error_file |
错误日志路径 | ./logs/error.log |
out_file |
标准输出日志路径 | ./logs/out.log |
log_date_format |
日志时间格式 | 'YYYY-MM-DD HH:mm:ss Z' |
merge_logs |
多实例合并日志 | true |
2.3 启动方式
# 方式1:使用 .env 文件(推荐)
cd /home/prod/game_server
pm2 start ecosystem.config.js
# 方式2:命令行传入环境变量
cd /home/prod/game_server
WX_APPID=xxx WX_SECRET=xxx pm2 start ecosystem.config.js
# 方式3:指定环境
pm2 start ecosystem.config.js --env production
3. PM2 日志管理详解
3.1 什么是 pm2-logrotate?
pm2-logrotate 是 PM2 官方提供的日志轮转插件,用于自动管理 PM2 进程产生的日志文件。
3.2 为什么需要 pm2-logrotate?
| 问题 | 说明 |
|---|---|
| 磁盘空间 | 日志文件会不断增长,不管理会导致磁盘满 |
| 性能下降 | 日志文件过大会影响写入性能 |
| 难以查看 | 大文件难以打开和搜索 |
没有日志轮转的后果:
- 日志文件从 MB 增长到 GB
- 最终磁盘写满 → 服务崩溃
- 无法生成新日志 → 无法排查问题
3.3 工作原理
# 安装前
game-server-out.log (无限增长 -> 1GB -> 10GB)
# 安装后
game-server-out.log (当前正在写入)
game-server-out.log.1 (轮转后的旧文件)
game-server-out.log.2 (更早的旧文件)
...
当日志文件达到配置大小或时间条件时,pm2-logrotate 会:
- 关闭当前日志文件
- 创建新日志文件继续写入
- 压缩或删除旧的日志文件
3.4 安装和配置命令
# 1. 安装 pm2-logrotate 插件
pm2 install pm2-logrotate
# 2. 配置单个日志文件最大大小(超过后轮转)
pm2 set pm2-logrotate:max_size 10M
# 3. 配置保留的文件数量(超过数量会删除旧的)
pm2 set pm2-logrotate:retain 5
# 4. 是否压缩旧文件(节省空间)
pm2 set pm2-logrotate:compress true
# 5. 配置轮转时间(可选,默认每天)
pm2 set pm2-logrotate:rotateInterval '0 3 * * *'
# 6. 查看当前配置
pm2 set
3.5 参数详解
| 参数 | 说明 | 示例值 |
|---|---|---|
max_size |
单个日志文件最大大小 | 10M (10MB) |
retain |
保留的文件数量 | 5 |
compress |
是否压缩旧文件 | true / false |
rotateInterval |
轮转时间cron表达式 | 0 3 * * * (每天凌晨3点) |
3.6 手动执行轮转
# 手动触发一次轮转
pm2 reloadLogs
# 查看日志文件
ls -lh ~/.pm2/logs/
3.7 注意事项
| 注意事项 | 说明 |
|---|---|
| 只对 PM2 捕获的日志有效 | 对 MongoDB 等第三方进程无效 |
| 需要安装插件 | pm2 install pm2-logrotate |
| 配置后立即生效 | 不需要重启 PM2 |
4. 常见问题与解决方案
4.1 查看日志的常用命令
在排查问题前,首先需要查看日志。以下是常用命令:
# 查看所有服务的日志(实时)
pm2 logs
# 查看指定服务的日志
pm2 logs game-server
# 只看错误日志
pm2 logs game-server --err
# 查看最近 50 行日志
pm2 logs --lines 50
# 实时查看错误日志
pm2 logs game-server --err --lines 20
# 查看日志文件(适用于已轮转的日志)
cat ~/.pm2/logs/game-server-out.log
tail -f ~/.pm2/logs/game-server-out.log
# 查看日志文件大小
ls -lh ~/.pm2/logs/
问题 2:端口被占用
错误:
Error: listen EADDRINUSE: address already in use :::3000
解决:
# 查看占用端口的进程
lsof -i:3000
# 停止占用进程
kill -9
# 或查看 PM2 进程
pm2 list
pm2 delete <进程名>
问题 3:进程启动失败
错误:
Process crashed with code '1'
解决:
# 查看错误日志
pm2 logs <进程名>
# 常见原因:
# 1. 缺少依赖 - 重新安装 npm install
# 2. 启动命令错误 - 检查 script 和 args
# 3. 权限不足 - 检查文件权限
# 4. 环境变量缺失 - 检查 .env 文件
问题 4:内存持续增长
错误:
PM2 memory usage: 1.2GB
解决:
# 检查内存使用
pm2 monit
# 配置自动重启
max_memory_restart: '1G'
# 查看内存泄漏
# 1. 重启进程
pm2 restart <进程名>
# 2. 观察内存增长趋势
问题 5:进程不断重启
原因:
- 进程崩溃后立即重启
- 配置了
autorestart: true
解决:
# 查看重启日志
pm2 logs --err --lines 50
# 临时禁用自动重启
pm2 stop <进程名>
# 修复问题后重新启动
pm2 restart <进程名>
问题 6:服务器重启后服务没有自动启动
解决:
# 保存当前进程列表
pm2 save
# 如果还是不行,检查 startup 脚本
pm2 startup
# 按照输出命令执行
问题 7:环境变量不生效
原因:
- .env 文件位置不对
- NODE_ENV 判断错误
解决:
# 检查 .env 文件位置(必须在 cwd 目录下)
# 当前配置 cwd: '/home/prod/game_server'
# 所以 .env 必须在 /home/prod/game_server/.env
# 检查环境变量
pm2 show <进程名>
# 查看 env 字段
# 手动传入测试
NODE_ENV=production pm2 start ecosystem.config.js
问题 8:日志文件过大
原因:
- 没有安装 pm2-logrotate
- pm2-logrotate 未正确配置
解决:
# 1. 安装 pm2-logrotate
pm2 install pm2-logrotate
# 2. 配置参数
pm2 set pm2-logrotate:max_size 10M # 单个日志最大 10MB
pm2 set pm2-logrotate:retain 5 # 保留 5 个文件
pm2 set pm2-logrotate:compress true # 压缩旧文件
# 3. 查看配置
pm2 set
# 4. 手动触发轮转测试
pm2 reloadLogs
问题 9:MongoDB 启动失败
错误:
mongod: error: '/data/gamedb' does not exist
解决:
# 创建数据目录
sudo mkdir -p /data/gamedb
# 设置权限
sudo chown -R $(whoami) /data/gamedb
# 重新启动
pm2 restart mongodb
附录:快速参考命令
# 启动所有服务
pm2 start ecosystem.config.js
# 查看进程状态
pm2 list
pm2 status
# 查看日志
pm2 logs # 所有日志
pm2 logs game-server # 指定服务日志
# 重启/停止
pm2 restart all # 重启所有
pm2 stop all # 停止所有
pm2 delete all # 删除所有进程
# 保存配置(服务器重启后自动启动)
pm2 save
# 查看详细信息
pm2 show game-server
# 监控资源
pm2 monit
# 安装日志轮转
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 5