以前用过supervisor,配置起来挺麻烦的,而且那个web界面丑得要命。后来听朋友说PM2挺好用,就研究了一下,这一用就离不开了。现在我们生产环境所有的Node.js服务、Python脚本,甚至一些定时任务都用PM2在管理,稳得一批。
PM2全称是Process Manager 2,是个带负载均衡功能的Node.js应用进程管理器[2]。说白了就是帮你管理进程的,进程挂了它能自动重启,还能监控进程状态、日志管理什么的。虽然它是为Node.js设计的,但其实管理其他语言的应用也没问题,比如Python、Shell脚本这些都可以。
我刚开始也以为PM2只能管理Node.js应用,后来发现我想简单了。PM2本质上是个进程守护工具,只要是个能跑的进程,它基本都能管。我现在用它管理了好几个Python爬虫脚本,还有几个定时任务,运行了大半年了,稳得不行。
安装这块其实没啥好说的,很简单。你的服务器上只要有Node.js环境就行,没有的话先装个Node.js。
npm install -g pm2装完之后可以看看版本:
pm2 -v
我现在的版本是6.0.14,这个工具更新还挺勤快的,时不时就有新版本[2]。建议隔段时间升级一下,新版本会修复一些bug,也能带来新功能。
升级命令:
npm install -g pm2@latest这块是重点,我把平时常用的命令都整理出来,都是实际工作中经常用到的。
最简单的启动方式:
pm2 start app.js这个app.js是你的Node.js入口文件。启动后PM2会给这个应用分配一个id和名字,默认名字就是文件名。
如果你想给应用起个名字,方便管理:
pm2 start app.js --name my-api这样在进程列表里显示的就是my-api,而不是app.js了。
启动Python脚本的话:
pm2 start test.py --interpreter python3这里要注意指定解释器,不然PM2可能会用默认的python,如果你的脚本是python3写的,可能会报错。
我之前就踩过这个坑,有个脚本用的python3的语法,结果PM2默认用python2去执行,各种报错。后来加了--interpreter python3就好了。
pm2 list或者简写:
pm2 ls这个命令会列出所有PM2管理的进程,包括进程id、名字、状态、CPU占用、内存占用这些信息。我每天上班第一件事就是pm2 ls看看所有服务是不是正常。

pm2 show app-name或者用进程id:
pm2 show 0这个命令能看到进程的详细信息,包括启动时间、重启次数、脚本路径、日志路径什么的。有一次排查问题,发现某个服务重启了50多次,一看日志才发现是数据库连接配置错了,一直在重连。
pm2 monit这个命令会打开一个监控面板,实时显示所有进程的CPU和内存使用情况,还能看到日志输出。不过我平时用得不多,一般还是用pm2 list和pm2 logs比较多。


pm2 logs这个命令会显示所有进程的日志,实时滚动的。如果只想看某个进程的日志:
pm2 logs app-name日志这块PM2做得挺好的,它会自动把标准输出和错误输出都记录下来,而且会按日期分割日志文件。日志默认存放在~/.pm2/logs/目录下[4]。
有时候日志太多,想清空一下:
pm2 flush这个命令会清空所有日志文件。不过要小心,清空了就找不回来了,我一般会先备份一下。
pm2 restart app-name或者重启所有应用:
pm2 restart all重启这个操作在生产环境要谨慎,最好在业务低峰期做。我们有个服务重启要10多秒,白天重启的话会影响用户使用。
停止某个应用:
pm2 stop app-name停止所有:
pm2 stop all删除某个应用:
pm2 delete app-name删除所有:
pm2 delete all停止和删除的区别是,停止后应用还在PM2的管理列表里,删除就是彻底移除了。一般临时维护用stop,要彻底下线一个服务用delete。
这个命令很重要,一定要记住:
pm2 save这个命令会把当前PM2管理的所有进程信息保存下来。如果不save,服务器重启后PM2里的进程就都没了,得手动一个个启动。
恢复的话:
pm2 resurrect或者更常用的方式是配合开机自启动。
pm2 startup执行这个命令后,PM2会生成一个系统服务,实现开机自启动[2]。执行完会提示你复制一条命令执行,照着做就行了。
然后记得:
pm2 save这样服务器重启后,PM2会自动启动,并且恢复之前save的所有进程。
我第一次用PM2的时候不知道这个,服务器重启后所有服务都没了,吓得我赶紧手动启动。后来才知道有startup这个命令,真是血泪教训。
这块单独拿出来说,因为很多人不知道PM2还能管理Python应用。我之前也以为PM2只能管理Node.js,后来发现完全不是这么回事。
直接启动:
pm2 start test.py --interpreter python3指定应用名:
pm2 start test.py --interpreter python3 --name my-python-app我有个数据采集的Python脚本,每5分钟跑一次,用crontab管理总是出问题,有时候脚本挂了都不知道。后来改用PM2管理,脚本异常退出PM2会自动重启,还能看日志,方便多了。

如果你用的是Flask或者Django这类Web框架,PM2也能管理。
Flask应用:
pm2 start app.py --interpreter python3 --name flask-api不过要注意,Flask默认是单进程的,并发高的话性能不行。可以用gunicorn配合PM2:
pm2 start "gunicorn -w 4 -b 0.0.0.0:8000 app:app" --name flask-api这样就能启动4个工作进程,性能好很多。
Django的话类似:
pm2 start "gunicorn -w 4 -b 0.0.0.0:8000 myproject.wsgi" --name django-api如果参数比较多,用命令行就有点麻烦了,可以用配置文件。PM2支持ecosystem.config.js配置文件[2]。
创建配置文件:
pm2 ecosystem会生成一个ecosystem.config.js文件,内容大概是这样:
module.exports = {
apps : [{
name: "python-script",
script: "test.py",
interpreter: "python3",
watch: true,
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}]
}然后启动:
pm2 start ecosystem.config.js配置文件的好处是所有配置都写在一起,方便管理,也方便版本控制。我们团队现在所有服务都用配置文件管理,谁改了什么一目了然。
既然说到配置文件了,就详细说说。配置文件能做的事情挺多的,不只是启动应用那么简单。
module.exports = {
apps: [{
name: 'my-api',
script: './app.js',
cwd: '/data/www/my-project',
args: '--port=3000',
interpreter: 'node',
instances: 2,
exec_mode: 'cluster',
watch: false,
max_memory_restart: '1G',
autorestart: true,
max_restarts: 10,
restart_delay: 1000,
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 80
},
error_file: './logs/app-error.log',
out_file: './logs/app-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss',
merge_logs: true
}]
}一个个参数解释一下:
这个要重点说说。cluster模式能让你的应用利用多核CPU,提升性能[2]。
{
name: 'my-api',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster'
}instances可以设置具体数字,也可以设置'max',max就是CPU有几个核就启动几个实例。
不过要注意,不是所有应用都适合cluster模式。如果你的应用有状态,比如用了内存session,cluster模式可能会有问题。我之前就遇到过,用户登录后刷新页面就退出了,就是因为session存在内存里,不同实例之间不共享。后来改用Redis存session就好了。
开发环境挺好用的,文件改动后自动重启:
{
watch: true,
ignore_watch: ['node_modules', 'logs']
}ignore_watch可以忽略某些文件或目录,不然改个node_modules里的文件也重启,太频繁了。
不过生产环境不建议开启watch,万一有人误操作改了文件,服务自动重启就麻烦了。
PM2在生产环境用得挺多的,我们公司现在所有Node.js服务都用PM2管理[5]。说说一些经验吧。
一定要设置内存限制:
{
max_memory_restart: '1G'
}Node.js有内存泄漏的问题,时间长了内存占用会越来越高,设置这个参数能让应用在内存超标时自动重启,防止把服务器内存吃光。
我们有个服务就是这样,运行一周后内存能到2G多,后来加了内存限制,每天自动重启一次,问题就解决了。
PM2的日志会一直增长,时间长了能把磁盘撑爆。可以用pm2-logrotate模块来自动分割日志:
pm2 install pm2-logrotate安装后会自动按大小和日期分割日志,还能设置保留多少个日志文件。
PM2有个监控平台叫PM2 Plus,可以实时监控所有进程的状态,还能设置告警规则。不过这个是收费的,免费版功能有限。
我们现在是配合Prometheus和Grafana做的监控,PM2有个metrics接口,能导出进程的各项指标,然后Prometheus采集数据,Grafana展示。这样就能看到CPU、内存、重启次数这些数据,还能设置告警。
生产环境重启服务要注意,不能直接kill进程,不然用户的请求可能会中断。PM2支持优雅重启:
pm2 gracefulReload app-name这个命令会等现有请求处理完再重启,不会中断用户请求。不过要你的应用支持这个功能才行,需要在应用里监听一些信号。
定期备份PM2的配置:
pm2 save这个命令会把当前进程列表保存到~/.pm2/dump.pm2文件里。万一PM2出问题,可以用这个文件恢复:
pm2 resurrect我还会把ecosystem.config.js文件提交到git,这样就算服务器挂了,在新服务器上拉代码直接启动就行。
有时候服务器重启后PM2里的进程都没了,一般是没执行pm2 save。记得每次修改进程配置后都要save一下。
还有就是检查一下开机自启动有没有配置:
pm2 startupPM2的日志文件会一直增长,几个G甚至几十G都有可能。用pm2-logrotate模块自动分割,或者定期手动清理:
pm2 flush不过flush会清空所有日志,谨慎使用。
如果发现某个进程重启次数特别多,先看日志:
pm2 logs app-name一般是应用本身有问题,比如代码报错、数据库连不上这些。找到原因修复就行。
也可以设置最大重启次数,防止无限重启:
{
max_restarts: 10,
restart_delay: 3000
}启动应用时报端口被占用,先看看是不是有其他进程在用这个端口:
netstat -tlnp | grep 3000如果是PM2自己管理的进程,可能是之前没停干净:
pm2 delete all
pm2 killpm2 kill会彻底停止PM2守护进程,然后再重新启动。
这个问题前面其实已经回答了,答案是肯定的。除了Node.js和Python,PM2还能管理很多其他类型的应用[1]。
pm2 start test.sh --interpreter bash我有个定时备份的shell脚本,之前用crontab管理,后来改用PM2,脚本里写个死循环加sleep,PM2负责守护,异常退出自动重启,稳定多了。
理论上只要能通过命令行启动的程序,PM2都能管理。比如Ruby、PHP这些:
pm2 start app.rb --interpreter ruby
pm2 start index.php --interpreter php甚至二进制程序都行:
pm2 start ./my-binary不过要注意,有些程序可能不太适合用PM2管理,比如需要交互输入的程序,或者会主动退出的程序。PM2设计是管理长期运行的服务,如果你的程序运行完就退出,PM2会认为它崩溃了,然后不断重启。
很多人会问PM2和Supervisor哪个好,我两个都用过,简单说说感受。
Supervisor是个老牌的进程管理工具,Python写的,配置文件是ini格式。优点是稳定,功能也够用,很多大公司都在用。缺点是配置比较麻烦,每个进程都要写一段配置,web界面也比较简陋。
PM2相对新一些,Node.js写的,配置可以用命令行也可以用配置文件。优点是配置简单,命令行工具强大,监控功能完善,还有cluster模式支持负载均衡。缺点是依赖Node.js环境,如果你的服务器上没有Node.js,还得先装一个。
我个人更倾向于PM2,主要是用起来方便,命令行工具很强大,日志管理也做得好。不过如果你的应用都是Python的,不想装Node.js,用Supervisor也完全没问题,两个工具都能满足生产环境的需求[1]。
PM2这个工具用了快两年了,从最开始的简单进程管理,到现在配合监控告警、日志分析,算是摸透了。现在我们生产环境所有的服务都用PM2管理,Node.js的、Python的、Shell脚本的,加起来有30多个进程,运行得很稳定。
说真的,进程管理这块,PM2确实做得不错。自动重启、日志管理、监控面板这些功能都很实用,而且配置简单,上手快。如果你还在用nohup、screen这些原始方式管理进程,真的建议试试PM2,会打开新世界的大门。
当然,工具只是工具,关键还是要理解原理,知道它在做什么。PM2本质上就是个守护进程,帮你启动和管理子进程,监控它们的状态,异常时重启。理解了这些,用起来就更得心应手了。
最后再说一句,PM2是可以在生产环境使用的,很多大公司都在用,稳定性没问题。不过任何工具都要根据实际情况配置,内存限制、日志分割、监控告警这些该配的都要配上,才能真正发挥作用。
公众号:运维躬行录
个人博客:躬行笔记
觉得有用的话点个关注呗,我会持续分享运维相关的实战经验,都是踩过的坑总结出来的干货。有问题也欢迎留言交流,一起学习进步!