nodejs实践录:pm2使用

本文介绍pm2的基本使用方法。主要针对pm2的命令,有关配置 文件ecosystem.config.js的细节,后文将进行讲解。

重要教训

在生产环境中,谨慎使用pm2 killpm2 restart all这样全局性的操作。
笔者就误操作过一次,将生产服务器上所有pm2实例都干掉,还好有同事帮助,在短时间内恢复了,甲方公司那边没感知。

生成ecosystem.config.js文件

在工程目录输入:

1
pm2 ecosystem

默认使用的是ecosystem.config.js,实际应用中,根据不同的服务,创建不同的配置文件,各自处理(包括启动、停止,等)。

启动

1
2
pm2 start(有ecosystem.config.js情况下)
pm2 start app.js(指定某个js文件)

停止

1
pm2 stop <PID>

注:stop只是停止了,但不是真正的删除。使用kill,才是真正的“删除”。

删除所有pm2管理的实例

1
pm2 kill

pm2的管理是全局的,不管在哪个目录,执行kill操作都会删除所有的实例!,在生产环境中务必谨慎!

删除指定实例

1
pm2 del <实例ID/实例名称>

删除某个实例,成功后,使用pm2 list可查看实例已不存在。如果重新启动配置文件,同一名称的实例,占用的实例ID是新的(原来已占用的,会被pm2保留,直接执行pm2 kill后释放),可以认为是一个新的实例。这与pm2 stop是不同的。

重启

1
pm2 startOrGracefulReload ecosystem.config.js
1
pm2 startOrRestart ecosystem.config.js
1
2
3
pm2 reload ecosystem.config.js
pm2 reload all // 重载所有进程
pm2 reload foobar // 只重载foobar实例
1
2
pm2 restart ecosystem.config.js
pm2 restart all

上面的方式,不管是startOrGracefulReload、restart还是reload,是不会更新环境变量的,就是说,即便修改了ecosystem.config.js文件的环境变量,也没有效果。pm2提供了--update-env选项,可达到目的。

更新ecosystem.config.js文件的环境变量:

1
pm2 reload ecosystem.config.js --update-env

注意,restart会重新启动进程,如果是socket服务,会提示端口被占用。 ——存疑:未经多次验证。

只启动其中一个实例

1
2
pm2 start ecosystem.config.js  --only app1
pm2 reload ecosystem.config.js --only app1

禁止pm2日志

原由:mp2日志默认在<当前用户目录>/.pm2/logs下,除非删除,随着时间增长而增长,参考网上做法进行测试验证:
测试1:

1
pm2 reload ecosystem.config.js  -l logggs

测试2:

1
2
pm2 stop ecosystem.config.js
pm2 start ecosystem.config.js -l logggs

测试3:

1
2
pm2 stop ecosystem.config.js
pm2 start ecosystem.config.js -o "/dev/null" -e "/dev/null"

注:均无效,待继续验证。

常用用法

启动时,使用生产环境:

1
pm2 start --env production

重启时,使用生产环境:

1
pm2 restart --env production

pm2插件

日志模块pm2-logrotate:
安装:

1
pm2 install pm2-logrotate

日志:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[PM2][Module] Installing NPM pm2-logrotate module
[PM2][Module] Calling [NPM] to install pm2-logrotate ...
+ pm2-logrotate@2.6.0
added 325 packages from 296 contributors and audited 2459 packages in 35.768s
found 0 vulnerabilities

[PM2][Module] Module downloaded
[PM2][WARN] Applications pm2-logrotate not running, starting...
[PM2] App [pm2-logrotate] launched (1 instances)
== pm2-logrotate ==
───────────────┬─────────────────────┐
│ key │ value │
├────────────────┼─────────────────────┤
│ max_size │ 10M │
│ retain │ 30 │
│ compress │ false │
│ dateFormat │ YYYY-MM-DD_HH-mm-ss │
│ workerInterval │ 30 │
│ rotateInterval │ 0 0 * * * │
│ rotateModule │ true │
└────────────────┴─────────────────────┘
[PM2][Module] Module successfully installed and launched
[PM2][Module] Edit configuration via: `pm2 conf`

使用pm2 list可查看已运行的模块。

删除pm2-logrotate:

1
pm2 uninstall pm2-logrotate

pm2自动运行

如果想让机器重启后,pm2能自动启动,则以root权限执行:

1
2
3
4
5
pm2 startup [平台名称]
示例:
pm2 startup

pm2 startup ubuntu

即可。平台名称支持的有:

1
ubuntu, centos, redhat, gentoo, systemd, darwin, amazon.

实际测试时发现,不输出平台名称,则pm2会自己去搜索并确定使用哪一个平台。

如果要取消开机自动运行,执行:  

1
2
3
pm2 unstartup

pm2 unstartup ubuntu

要保存pm2已经管理的实例,执行:  

1
pm2 save

注:没看到了取消保存的命令,测试发现,取消开机自动运行pm2,就会自动删除保存的实例。  

下面给出一些日志信息。  
开机自动运行:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pm2 startup
[sudo] password for latelee:
[PM2] Init System found: systemd
Platform systemd
Template
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target

[Service]
Type=forking
User=root
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/usr/local/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/home/latelee/.pm2
PIDFile=/home/latelee/.pm2/pm2.pid

ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill

[Install]
WantedBy=multi-user.target

Target path
/etc/systemd/system/pm2-root.service
Command list
[ 'systemctl enable pm2-root' ]
[PM2] Writing init configuration in /etc/systemd/system/pm2-root.service
[PM2] Making script booting at startup...
[PM2] [-] Executing: systemctl enable pm2-root...
Created symlink from /etc/systemd/system/multi-user.target.wants/pm2-root.service to /etc/systemd/system/pm2-root.service.
[PM2] [v] Command successfully executed.
+---------------------------------------+
[PM2] Freeze a process list on reboot via:
$ pm2 save

[PM2] Remove init script via:
$ pm2 unstartup systemd

保存实例:  

1
2
3
# pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/latelee/.pm2/dump.pm2

取消开机自动运行:  

1
2
3
4
5
6
7
pm2 unstartup
[PM2] Init System found: systemd
Removed symlink /etc/systemd/system/multi-user.target.wants/pm2-root.service.

Removed symlink /etc/systemd/system/multi-user.target.wants/pm2-root.service.

[PM2] Init file disabled.

出错及处理:  

1
2
3
$ pm2 list
[PM2][ERROR] Permission denied, to give access to current user:
$ sudo chown latelee:latelee /home/latelee/.pm2/rpc.sock /home/latelee/.pm2/pub.sock

执行sudo chown latelee:latelee /home/latelee/.pm2/rpc.sock /home/latelee/.pm2/pub.sock即可。原因应该是系统自动执行时,会以root执行,权限就变化了。  

集群模式

调整实例数量:

1
2
pm2 scale <实例名称> <数量>
pm2 scale app 4

使用经验

参考资料

http://www.augustkleimo.com/how-to-run-nodejs-using-pm2-on-amazon-ec2-linux/
http://pm2.keymetrics.io/docs/usage/application-declaration/

李迟 2019.2.5 周二