首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >生产环境必备神器PM2,让你的服务稳如老狗!

生产环境必备神器PM2,让你的服务稳如老狗!

作者头像
悠悠12138
发布2026-04-15 17:38:45
发布2026-04-15 17:38:45
40
举报

以前用过supervisor,配置起来挺麻烦的,而且那个web界面丑得要命。后来听朋友说PM2挺好用,就研究了一下,这一用就离不开了。现在我们生产环境所有的Node.js服务、Python脚本,甚至一些定时任务都用PM2在管理,稳得一批。

PM2到底是啥

PM2全称是Process Manager 2,是个带负载均衡功能的Node.js应用进程管理器[2]。说白了就是帮你管理进程的,进程挂了它能自动重启,还能监控进程状态、日志管理什么的。虽然它是为Node.js设计的,但其实管理其他语言的应用也没问题,比如Python、Shell脚本这些都可以。

我刚开始也以为PM2只能管理Node.js应用,后来发现我想简单了。PM2本质上是个进程守护工具,只要是个能跑的进程,它基本都能管。我现在用它管理了好几个Python爬虫脚本,还有几个定时任务,运行了大半年了,稳得不行。

安装PM2

安装这块其实没啥好说的,很简单。你的服务器上只要有Node.js环境就行,没有的话先装个Node.js。

代码语言:javascript
复制
npm install -g pm2

装完之后可以看看版本:

代码语言:javascript
复制
pm2 -v

我现在的版本是6.0.14,这个工具更新还挺勤快的,时不时就有新版本[2]。建议隔段时间升级一下,新版本会修复一些bug,也能带来新功能。

升级命令:

代码语言:javascript
复制
npm install -g pm2@latest

PM2常用操作命令

这块是重点,我把平时常用的命令都整理出来,都是实际工作中经常用到的。

启动应用

最简单的启动方式:

代码语言:javascript
复制
pm2 start app.js

这个app.js是你的Node.js入口文件。启动后PM2会给这个应用分配一个id和名字,默认名字就是文件名。

如果你想给应用起个名字,方便管理:

代码语言:javascript
复制
pm2 start app.js --name my-api

这样在进程列表里显示的就是my-api,而不是app.js了。

启动Python脚本的话:

代码语言:javascript
复制
pm2 start test.py --interpreter python3

这里要注意指定解释器,不然PM2可能会用默认的python,如果你的脚本是python3写的,可能会报错。

我之前就踩过这个坑,有个脚本用的python3的语法,结果PM2默认用python2去执行,各种报错。后来加了--interpreter python3就好了。

查看进程列表

代码语言:javascript
复制
pm2 list

或者简写:

代码语言:javascript
复制
pm2 ls

这个命令会列出所有PM2管理的进程,包括进程id、名字、状态、CPU占用、内存占用这些信息。我每天上班第一件事就是pm2 ls看看所有服务是不是正常。

查看进程详情

代码语言:javascript
复制
pm2 show app-name

或者用进程id:

代码语言:javascript
复制
pm2 show 0

这个命令能看到进程的详细信息,包括启动时间、重启次数、脚本路径、日志路径什么的。有一次排查问题,发现某个服务重启了50多次,一看日志才发现是数据库连接配置错了,一直在重连。

监控面板

代码语言:javascript
复制
pm2 monit

这个命令会打开一个监控面板,实时显示所有进程的CPU和内存使用情况,还能看到日志输出。不过我平时用得不多,一般还是用pm2 list和pm2 logs比较多。

查看日志

代码语言:javascript
复制
pm2 logs

这个命令会显示所有进程的日志,实时滚动的。如果只想看某个进程的日志:

代码语言:javascript
复制
pm2 logs app-name

日志这块PM2做得挺好的,它会自动把标准输出和错误输出都记录下来,而且会按日期分割日志文件。日志默认存放在~/.pm2/logs/目录下[4]。

有时候日志太多,想清空一下:

代码语言:javascript
复制
pm2 flush

这个命令会清空所有日志文件。不过要小心,清空了就找不回来了,我一般会先备份一下。

重启应用

代码语言:javascript
复制
pm2 restart app-name

或者重启所有应用:

代码语言:javascript
复制
pm2 restart all

重启这个操作在生产环境要谨慎,最好在业务低峰期做。我们有个服务重启要10多秒,白天重启的话会影响用户使用。

停止和删除

停止某个应用:

代码语言:javascript
复制
pm2 stop app-name

停止所有:

代码语言:javascript
复制
pm2 stop all

删除某个应用:

代码语言:javascript
复制
pm2 delete app-name

删除所有:

代码语言:javascript
复制
pm2 delete all

停止和删除的区别是,停止后应用还在PM2的管理列表里,删除就是彻底移除了。一般临时维护用stop,要彻底下线一个服务用delete。

保存和恢复

这个命令很重要,一定要记住:

代码语言:javascript
复制
pm2 save

这个命令会把当前PM2管理的所有进程信息保存下来。如果不save,服务器重启后PM2里的进程就都没了,得手动一个个启动。

恢复的话:

代码语言:javascript
复制
pm2 resurrect

或者更常用的方式是配合开机自启动。

开机自启动

代码语言:javascript
复制
pm2 startup

执行这个命令后,PM2会生成一个系统服务,实现开机自启动[2]。执行完会提示你复制一条命令执行,照着做就行了。

然后记得:

代码语言:javascript
复制
pm2 save

这样服务器重启后,PM2会自动启动,并且恢复之前save的所有进程。

我第一次用PM2的时候不知道这个,服务器重启后所有服务都没了,吓得我赶紧手动启动。后来才知道有startup这个命令,真是血泪教训。

PM2管理Python应用

这块单独拿出来说,因为很多人不知道PM2还能管理Python应用。我之前也以为PM2只能管理Node.js,后来发现完全不是这么回事。

简单的Python脚本

直接启动:

代码语言:javascript
复制
pm2 start test.py --interpreter python3

指定应用名:

代码语言:javascript
复制
pm2 start test.py --interpreter python3 --name my-python-app

我有个数据采集的Python脚本,每5分钟跑一次,用crontab管理总是出问题,有时候脚本挂了都不知道。后来改用PM2管理,脚本异常退出PM2会自动重启,还能看日志,方便多了。

Python Web应用

如果你用的是Flask或者Django这类Web框架,PM2也能管理。

Flask应用:

代码语言:javascript
复制
pm2 start app.py --interpreter python3 --name flask-api

不过要注意,Flask默认是单进程的,并发高的话性能不行。可以用gunicorn配合PM2:

代码语言:javascript
复制
pm2 start "gunicorn -w 4 -b 0.0.0.0:8000 app:app" --name flask-api

这样就能启动4个工作进程,性能好很多。

Django的话类似:

代码语言:javascript
复制
pm2 start "gunicorn -w 4 -b 0.0.0.0:8000 myproject.wsgi" --name django-api

用配置文件管理Python应用

如果参数比较多,用命令行就有点麻烦了,可以用配置文件。PM2支持ecosystem.config.js配置文件[2]。

创建配置文件:

代码语言:javascript
复制
pm2 ecosystem

会生成一个ecosystem.config.js文件,内容大概是这样:

代码语言:javascript
复制
module.exports = {
  apps : [{
    name: "python-script",
    script: "test.py",
    interpreter: "python3",
    watch: true,
    env: {
      NODE_ENV: "development",
    },
    env_production: {
      NODE_ENV: "production",
    }
  }]
}

然后启动:

代码语言:javascript
复制
pm2 start ecosystem.config.js

配置文件的好处是所有配置都写在一起,方便管理,也方便版本控制。我们团队现在所有服务都用配置文件管理,谁改了什么一目了然。

PM2配置文件详解

既然说到配置文件了,就详细说说。配置文件能做的事情挺多的,不只是启动应用那么简单。

基础配置

代码语言:javascript
复制
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
  }]
}

一个个参数解释一下:

  • • name: 应用名称,这个随便起,方便识别就行
  • • script: 要启动的脚本路径
  • • cwd: 当前工作目录,脚本会在这个目录下执行
  • • args: 传给脚本的参数
  • • interpreter: 解释器,比如python3、bash这些
  • • instances: 启动多少个实例,cluster模式下有用
  • • exec_mode: 执行模式,有fork和cluster两种
  • • watch: 是否监听文件变化自动重启
  • • max_memory_restart: 内存超过这个值自动重启
  • • autorestart: 是否自动重启
  • • max_restarts: 最大重启次数,防止无限重启
  • • restart_delay: 重启延迟,单位毫秒
  • • env: 环境变量
  • • env_production: 生产环境的环境变量
  • • error_file: 错误日志路径
  • • out_file: 输出日志路径
  • • log_date_format: 日志时间格式
  • • merge_logs: 是否合并日志

cluster模式

这个要重点说说。cluster模式能让你的应用利用多核CPU,提升性能[2]。

代码语言:javascript
复制
{
  name: 'my-api',
  script: 'app.js',
  instances: 'max',
  exec_mode: 'cluster'
}

instances可以设置具体数字,也可以设置'max',max就是CPU有几个核就启动几个实例。

不过要注意,不是所有应用都适合cluster模式。如果你的应用有状态,比如用了内存session,cluster模式可能会有问题。我之前就遇到过,用户登录后刷新页面就退出了,就是因为session存在内存里,不同实例之间不共享。后来改用Redis存session就好了。

watch模式

开发环境挺好用的,文件改动后自动重启:

代码语言:javascript
复制
{
  watch: true,
  ignore_watch: ['node_modules', 'logs']
}

ignore_watch可以忽略某些文件或目录,不然改个node_modules里的文件也重启,太频繁了。

不过生产环境不建议开启watch,万一有人误操作改了文件,服务自动重启就麻烦了。

生产环境最佳实践

PM2在生产环境用得挺多的,我们公司现在所有Node.js服务都用PM2管理[5]。说说一些经验吧。

内存限制

一定要设置内存限制:

代码语言:javascript
复制
{
  max_memory_restart: '1G'
}

Node.js有内存泄漏的问题,时间长了内存占用会越来越高,设置这个参数能让应用在内存超标时自动重启,防止把服务器内存吃光。

我们有个服务就是这样,运行一周后内存能到2G多,后来加了内存限制,每天自动重启一次,问题就解决了。

日志管理

PM2的日志会一直增长,时间长了能把磁盘撑爆。可以用pm2-logrotate模块来自动分割日志:

代码语言:javascript
复制
pm2 install pm2-logrotate

安装后会自动按大小和日期分割日志,还能设置保留多少个日志文件。

监控告警

PM2有个监控平台叫PM2 Plus,可以实时监控所有进程的状态,还能设置告警规则。不过这个是收费的,免费版功能有限。

我们现在是配合Prometheus和Grafana做的监控,PM2有个metrics接口,能导出进程的各项指标,然后Prometheus采集数据,Grafana展示。这样就能看到CPU、内存、重启次数这些数据,还能设置告警。

优雅重启

生产环境重启服务要注意,不能直接kill进程,不然用户的请求可能会中断。PM2支持优雅重启:

代码语言:javascript
复制
pm2 gracefulReload app-name

这个命令会等现有请求处理完再重启,不会中断用户请求。不过要你的应用支持这个功能才行,需要在应用里监听一些信号。

备份恢复

定期备份PM2的配置:

代码语言:javascript
复制
pm2 save

这个命令会把当前进程列表保存到~/.pm2/dump.pm2文件里。万一PM2出问题,可以用这个文件恢复:

代码语言:javascript
复制
pm2 resurrect

我还会把ecosystem.config.js文件提交到git,这样就算服务器挂了,在新服务器上拉代码直接启动就行。

常见问题

PM2进程丢失

有时候服务器重启后PM2里的进程都没了,一般是没执行pm2 save。记得每次修改进程配置后都要save一下。

还有就是检查一下开机自启动有没有配置:

代码语言:javascript
复制
pm2 startup

日志文件太大

PM2的日志文件会一直增长,几个G甚至几十G都有可能。用pm2-logrotate模块自动分割,或者定期手动清理:

代码语言:javascript
复制
pm2 flush

不过flush会清空所有日志,谨慎使用。

进程频繁重启

如果发现某个进程重启次数特别多,先看日志:

代码语言:javascript
复制
pm2 logs app-name

一般是应用本身有问题,比如代码报错、数据库连不上这些。找到原因修复就行。

也可以设置最大重启次数,防止无限重启:

代码语言:javascript
复制
{
  max_restarts: 10,
  restart_delay: 3000
}

端口占用

启动应用时报端口被占用,先看看是不是有其他进程在用这个端口:

代码语言:javascript
复制
netstat -tlnp | grep 3000

如果是PM2自己管理的进程,可能是之前没停干净:

代码语言:javascript
复制
pm2 delete all
pm2 kill

pm2 kill会彻底停止PM2守护进程,然后再重新启动。

PM2能管理其他应用吗

这个问题前面其实已经回答了,答案是肯定的。除了Node.js和Python,PM2还能管理很多其他类型的应用[1]。

Shell脚本

代码语言:javascript
复制
pm2 start test.sh --interpreter bash

我有个定时备份的shell脚本,之前用crontab管理,后来改用PM2,脚本里写个死循环加sleep,PM2负责守护,异常退出自动重启,稳定多了。

其他语言

理论上只要能通过命令行启动的程序,PM2都能管理。比如Ruby、PHP这些:

代码语言:javascript
复制
pm2 start app.rb --interpreter ruby
pm2 start index.php --interpreter php

甚至二进制程序都行:

代码语言:javascript
复制
pm2 start ./my-binary

不过要注意,有些程序可能不太适合用PM2管理,比如需要交互输入的程序,或者会主动退出的程序。PM2设计是管理长期运行的服务,如果你的程序运行完就退出,PM2会认为它崩溃了,然后不断重启。

PM2 vs Supervisor

很多人会问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是可以在生产环境使用的,很多大公司都在用,稳定性没问题。不过任何工具都要根据实际情况配置,内存限制、日志分割、监控告警这些该配的都要配上,才能真正发挥作用。


公众号:运维躬行录

个人博客:躬行笔记

觉得有用的话点个关注呗,我会持续分享运维相关的实战经验,都是踩过的坑总结出来的干货。有问题也欢迎留言交流,一起学习进步!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维躬行录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PM2到底是啥
  • 安装PM2
  • PM2常用操作命令
    • 启动应用
    • 查看进程列表
    • 查看进程详情
    • 监控面板
    • 查看日志
    • 重启应用
    • 停止和删除
    • 保存和恢复
    • 开机自启动
  • PM2管理Python应用
    • 简单的Python脚本
    • Python Web应用
    • 用配置文件管理Python应用
  • PM2配置文件详解
    • 基础配置
    • cluster模式
    • watch模式
  • 生产环境最佳实践
    • 内存限制
    • 日志管理
    • 监控告警
    • 优雅重启
    • 备份恢复
  • 常见问题
    • PM2进程丢失
    • 日志文件太大
    • 进程频繁重启
    • 端口占用
  • PM2能管理其他应用吗
    • Shell脚本
    • 其他语言
  • PM2 vs Supervisor
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档