Ubuntu16.04-Node-PM2-自启动相关

322 阅读3分钟

近期,笔者对pm2程序的自启动进行了深入的研究,将遇到的问题与解决方案浅作记录。关于 pm2 这个 node 进程管理工具就不多赘述了,有疑问的小伙伴可以去看 @LeeChen 的一篇文章: Nodejs教程30(完结):PM2入门

PM2 实现 Node 程序的自启动

基于网络上的博客,目前最主流的实现方式为通过 pm2 startup命令创建自启动脚本,通过 PM2 运行需要自启动的 node 程序后,在命令行中执行pm2 save对该程序进行保存。这样系统启动后,就会自启动保存到 pm2 list 中的应用程序。然而,这种方法对笔者而言有两个致命的弊端:

  • 无法对应用程序进行更新 因为这个 pm2 save 是将程序的信息存到 /.pm2/dump.pm2 文件中,因此会导致,下次自启动的程序仍然是更新前的程序,这个缺陷还好解决,只需要在程序进行本地更新后,再执行一下 pm2 save 即可
  • 无法接入嵌入式的 CI/CD 笔者的项目需要接入到嵌入式的文件系统打包流程中,如果使用这种方法,那么打包固件时,每次都需要对文件系统中执行pm2 startup产生的 pm2-root.service 文件与 pm2 save产生的 dump.pm2 文件进行更新,也就是在文件打包时需要 run 一下被打包的 node 程序,然后重跑 pm2 save 指令以确保打包出的固件启动的确实是最新的程序,没有以前的缓存。因此,CI/CD 的接入就变得相当复杂,我便对其进行了优化。

PM2 程序自启动优化

1. 删除 pm2 save 的 应用信息 rm etc/.pm2/dump.pm2

当然,你的 dump.pm2 也有可能再root路径下,如果是 root 路径,则:

rm root/.pm2/dump.pm2

2. 删除 pm2 startup 服务 rm etc/systemd/system/muti-user.target.wants/pm2-root.service

3. 新建 pm2 自启动脚本 vi etc/init.d/pm2.sh

pm2.sh 里面的内容就是让你程序启动的一些命令即可,文件上方需要模板性注释:

### BEGIN INIT INFO
# Provides:          pm2.sh
# Required-start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the pm2.sh daemon
# Description:       starts pm2.sh using start-stop-daemon
### END INIT INFO

其中, pm2.sh 可以改成你命名的脚本名称,其他内容不可更改

4. 编辑 ubuntu16.04 的自启动脚本

vi etc/rc.local 将如下代码添加到 rc.local 的 exit0 之前

sh /etc/init.d/pm2.sh

5. 新建 pm2 运行环境 设置好启动脚本后,所有通过脚本启动的程序,它的环境都会是 PM2_HOME=/etc/.pm2/,我们平时在设备上进行调试的时候,pm2 ls 指令,环境都是 /root/.pm2/,这样就会导致自启动的程序无法被监控到。有两种解决方案,一个是输入 pm2 指令的时候前面带上 pm2 的运行环境 /etc,还有一个是直接在 profile 文件中修改 pm2 的环境,以后所有通过 pm2 指令启动的程序,都会在 /etc/.pm2/ 路径下。

若没有 nodejs.sh 文件,vi 仍旧可以新建一个文件,因此我们直接输入以下指令

vi etc/profile.d/nodejs.sh

将下列代码写入 nodejs.sh 文件中

export PM2_HOME=/etc/.pm2/

6. 查验程序自启动功能 以上步骤做完后,可以通过 reboot 指令去查看一下程序是否可以自启动成功,如果 pm2 ls 中没有,则说明启动失败了,可能是没有给 pm2.sh 文件可执行权限,只需要:

sudo chmod 755 /etc/init.d/pm2.sh

对其赋予权限,再进行验证即可。

PS: 本次优化是基于 arm32 位 ubuntu16.04 版本下的一次实践,若是其它系统,rc.loacl 位置或产生改变,需要根据系统版本灵活改变方案。