如果你在Windows上开发Node.js应用,肯定遇到过这样的场景:开了一堆命令行窗口运行不同的服务,突然某个服务崩溃了却没人发现;或者修改代码后要手动重启所有服务;又或者想查看某个服务的日志却要在几十个文件中翻找。传统解决方案是用批处理脚本(.bat)来启动和管理,但这种方式既原始又低效。
我在团队协作中就吃过亏:某个核心服务半夜崩溃,由于没有自动重启机制,直接导致第二天早上的线上事故。后来我们把所有Node.js服务都迁移到PM2管理,再也没出现过类似问题。PM2本质上是一个进程管理器,它能帮你:
特别值得一提的是,很多人以为PM2只能在Linux上用,其实Windows版功能同样完善。我经手过十几个Windows Server部署的Node.js项目,用PM2后运维效率提升了至少三倍。
首先确保已安装Node.js(建议LTS版本),然后全局安装PM2:
bash复制npm install pm2@latest -g
安装完成后,建议设置PM2开机自启动(这在服务器环境特别重要):
bash复制pm2 startup
pm2 save
注意:在Windows上执行
pm2 startup时可能需要管理员权限。如果遇到权限问题,可以右键用管理员身份运行命令行。
我习惯在项目根目录创建ecosystem.config.js文件,这是PM2的配置文件模板:
javascript复制module.exports = {
apps: [{
name: "my-app",
script: "./server.js",
instances: "max",
autorestart: true,
watch: true,
max_memory_restart: "1G",
env: {
NODE_ENV: "development"
},
env_production: {
NODE_ENV: "production"
}
}]
}
关键参数说明:
instances: "max":根据CPU核心数自动启动最大进程数watch: true:监听文件变动自动重启max_memory_restart:内存超过1GB自动重启在Windows上使用PM2有几个坑我踩过:
路径问题:Windows的反斜杠路径可能导致问题,建议:
javascript复制error_file: path.join(__dirname, "logs/err.log")
权限问题:如果遇到EACCES错误,可以:
bash复制pm2 start --node-args="--harmony" app.js
终端兼容性:部分旧版Windows终端可能导致日志显示异常,建议:
--no-treekill参数实际项目中我们通常需要区分开发/测试/生产环境。这是我的配置方案:
javascript复制module.exports = {
apps: [{
name: "app",
script: "./server.js",
instances: 2,
autorestart: true,
// 开发环境配置
env_development: {
NODE_ENV: "development",
PORT: 3000,
WATCH: true
},
// 生产环境配置
env_production: {
NODE_ENV: "production",
PORT: 80,
WATCH: false
}
}]
}
启动时指定环境:
bash复制pm2 start ecosystem.config.js --env production
PM2的日志系统很强大,但需要合理配置:
日志分割:安装pm2-logrotate
bash复制pm2 install pm2-logrotate
自定义日志格式:
javascript复制module.exports = {
apps: [{
// ...
log_date_format: "YYYY-MM-DD HH:mm Z",
merge_logs: true,
out_file: "/var/log/app-out.log",
error_file: "/var/log/app-err.log"
}]
}
实时日志追踪:
bash复制# 查看所有日志
pm2 logs
# 过滤特定应用
pm2 logs --lines=100 --raw app-name
我在项目中会额外配置日志报警,当错误日志中出现特定关键词时自动触发邮件通知。
Node.js是单线程的,但PM2可以轻松实现多进程:
bash复制pm2 start app.js -i max --name "api-cluster"
几个调优建议:
instances: "max"--max-memory-restart防止内存泄漏PM2内置监控工具:
bash复制# 终端仪表盘
pm2 monit
# 生成性能报告
pm2 report
对于生产环境,我推荐配合Keymetrics(PM2官方监控平台)使用:
bash复制pm2 link <secret> <public>
如果不想用第三方服务,也可以自己搭建监控:
javascript复制const pmx = require('pmx').init({
http: true, // 监控HTTP路由
errors: true, // 记录未捕获异常
custom_probes: true, // 自定义指标
network: true, // 监控网络
ports: true // 监控端口
});
遇到过几次pm2 stop无效的情况,解决方案:
pm2 deletebash复制taskkill /F /IM node.exe
Windows上经常出现端口被占用但PM2没完全释放的情况:
bash复制netstat -ano | findstr :3000
bash复制taskkill /PID <pid> /F
如果发现PM2服务没有随系统启动:
bash复制pm2 unstartup
pm2 startup
在实际DevOps流程中,我通常这样集成PM2:
部署脚本示例:
bash复制#!/bin/bash
pm2 stop all
git pull origin master
npm install
pm2 start ecosystem.config.js --env production
Docker集成方案:
dockerfile复制FROM node:14
WORKDIR /app
COPY . .
RUN npm install
RUN npm install pm2 -g
CMD ["pm2-runtime", "ecosystem.config.js"]
Jenkins Pipeline配置:
groovy复制stage('Deploy') {
steps {
bat 'pm2 reload ecosystem.config.js --env production'
}
}
对于已经在用脚本管理的项目,迁移到PM2只需三步:
分析现有启动命令:
bash复制# 原启动命令可能是:
node server.js --port 3000
转换为PM2配置:
javascript复制module.exports = {
apps: [{
name: "legacy-app",
script: "server.js",
args: "--port 3000"
}]
}
测试并切换:
bash复制pm2 start ecosystem.config.js
pm2 save
建议在迁移前先用pm2 start测试,确认无误后再替换原有启动方式。