如何使用PM2做进程管理

使用PM2让你的应用7*24永不离线

Posted by Jeremy Song on 2021-08-11
Estimated Reading Time 11 Minutes
Words 2.8k In Total
Viewed Times

简介

什么是PM2?

PM2 P(rocess) M(anager) 2 是一个内建了负载均衡器的守护进程管理器,可以帮助我们进行应用程序管理。通过PM2,可以保持我们的服务 7*24 在线,并且在服务重载的时候可以保证零停机。

PM2创建初期时专门为Node.js应用打造的,所以PM2是依赖于Node.js的。
当前PM2的稳定版本是 5.0.3,适用于所有 Linux, macOS 和 Windows的稳定版本,并且支持 Node.js 12.X 开始的所有 Node.js。

PM2项目的原始资料

此处记录一下PM2的官网资料传送门,防止迷路,其中资料都是英文的。如果你想先简单了解一下可以跳过这部分直接看下面的 如何安装PM2 章节。

PM2的特性

以上是官网站点上对PM2全特性的标签,上面的单词都很容易懂,就不做翻译了。如果你想了解更多相关特性的细节,可以前往 官方站点 首页查阅。

快速上手

本章节默认您的环境已经安装了Node.js, 如果您没有安装请先提前安装Node.js。
点击下载Node.js

安装PM2

  1. 使用 NPM 安装:
1
$ npm install pm2 -g
  1. 使用 YARN 安装:
1
$ yarn global add pm2
  1. 如果您没有Node.js,尝试使用如下安装方式:
    注意:本人尝试没成功,可能站点已经移除了,不建议使用
1
wget -qO- https://getpm2.com/install.sh | bash

启动应用

首先准备一个如下的Node.js服务器脚本,脚本名我们定为 app1.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const http = require('http')

const hostname = '127.0.0.1'
const port = 3001

const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('My Application 1\n')
})

server.listen(port, hostname, () => {
console.log(`服务器运行在 http://${hostname}:${port}/`)
})

使用如下命令来启动上述应用。

1
$ pm2 start app1.js

上图显示我们已经将app1启动成功了,验证一下:

启动语法介绍

使用 pm2 start xxx 的语法方式,我们启动 Node.js, Python, Ruby 以及其他在环境变量 $PATH 中设置了的二进制程序。例如:

1
2
3
$ pm2 start bashscript.sh
$ pm2 start python-app.py --watch
$ pm2 start binary-file -- --port 1520

启动命令可以使用的参数

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
# 指定应用名称
--name <app_name>

# 监视并且在文件发生变更时重启应用
--watch

# 设置应用重新加载的内存阈值
--max-memory-restart <200MB>

# 指定日志文件
--log <log_path>

# 将额外的参数传递给脚本
-- arg1 arg2 arg3

# 自动重启间的延迟
--restart-delay <delay in ms>

# 给日志加上时间戳前缀
--time

# 禁用自动重启应用
--no-autorestart

# 设置 cron 强制重启
--cron <cron_pattern>

# 附加到应用程序日志
--no-daemon

更多参数查看使用 pm2 -hpm2 start -h 命令查看。

进程管理

你可以复制上面的 app1.js 多创建几个服务来边写边练。记得修改每个js中的端口号,并使其不同。复制并修改完成后,您可以结合上面的启动命令并加上不同的参数来启动多个服务。

通过如下的命令可以列出正在运行中的服务列表:

1
$ pm2 list

显示结果可能如下,结果会根据您启动的服务不同而不同。

管理命令

PM2的管理命令都很简单直白,具体如下:

  • 列出运行中的服务列表,下面三种方式都可以
1
2
3
$ pm2 list
$ pm2 ls
$ pm2 status
  • 停止应用
1
$ pm2 stop     <app_name|namespace|id|'all'|json_conf>
  • 重启应用
1
$ pm2 restart     <app_name|namespace|id|'all'|json_conf>
  • 删除应用
1
$ pm2 delete     <app_name|namespace|id|'all'|json_conf>
  • 查看指定应用详情
1
$ pm2 describe <id|app_name>
1
$ pm2 show <id|app_name>
  • 监控日志,自定义智标和应用信息
1
$ pm2 monit

日志命令

  • 显示实时日志:
1
$ pm2 logs
  • 显示较早的日志:
1
$ pm2 logs --lines 200

集群模式

对于 Node.js 应用程序,PM2 包括一个自动负载平衡器,它将在每个衍生进程之间共享所有 HTTP[s]/Websocket/TCP/UDP 连接。
使用如下命令进行集群模式启动,其中 max 的值为当前系统的 CPU核心数减1 ,当然我们也可以改成任意数字,表示集群的实例数:

1
$ pm2 start app.js -i max

零离线重载

热重载允许在不停机的情况下更新应用程序。使用如下命令:

1
$ pm2 reload all

注:上面的all表示所有的服务进程,除此之外还可以使指定id, 或应用名称

开机启动

1
$ pm2 startup

冻结进程列表并自动复位:

1
$ pm2 save

PM2更新

简单直白的方法:

1
$ npm install pm2@latest -g

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
43
44
45
46
47
# Fork mode
pm2 start app.js --name my-api # Name process

# Cluster mode
pm2 start app.js -i 0 # Will start maximum processes with LB depending on available CPUs
pm2 start app.js -i max # Same as above, but deprecated.
pm2 scale app +3 # Scales `app` up by 3 workers
pm2 scale app 2 # Scales `app` up or down to 2 workers total

# Listing

pm2 list # Display all processes status
pm2 jlist # Print process list in raw JSON
pm2 prettylist # Print process list in beautified JSON

pm2 describe 0 # Display all informations about a specific process

pm2 monit # Monitor all processes

# Logs

pm2 logs [--raw] # Display all processes logs in streaming
pm2 flush # Empty all log files
pm2 reloadLogs # Reload all logs

# Actions

pm2 stop all # Stop all processes
pm2 restart all # Restart all processes

pm2 reload all # Will 0s downtime reload (for NETWORKED apps)

pm2 stop 0 # Stop specific process id
pm2 restart 0 # Restart specific process id

pm2 delete 0 # Will remove process from pm2 list
pm2 delete all # Will remove all processes from pm2 list

# Misc

pm2 reset <process> # Reset meta data (restarted time...)
pm2 updatePM2 # Update in memory pm2
pm2 ping # Ensure pm2 daemon has been launched
pm2 sendSignal SIGUSR2 my-app # Send system signal to script
pm2 start app.js --no-daemon
pm2 start app.js --no-vizion
pm2 start app.js --no-autorestart

我们还可以使用命令 pm2 examples 来查阅常用命令示例。

高级特性

PM2的配置文件

PM2的配置文件叫做生态系统文件(Ecosystem File),它管理着众多的应用。使用如下命令可以生成一个生态系统文件:

1
$ pm2 ecosystem

上面的命令执行完毕可以生成一个文件名为 ecosystem.config.js 的文件,内容大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports = {
apps : [{
script: 'index.js',
watch: '.'
}, {
script: './service-worker/',
watch: ['./service-worker']
}],

deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};

我们可以修改上述配置文件,然后使用命令 pm2 start ecosystem.config.js 的方法来启动新的服务。

这部分在这里就不多讲了,因为内容很多。如果您想了解更多关于PM2生态系统文件的内容以及配置文件中每个字段的属性和含义可以在官方文档中找到。
点此查看 PM2 ecosystem 使用指导

为什么这里要提这个PM2 ecosystem,而不愿意多讲呢。因为下面要讲的如何使用PM2来启动和管理非Node.js程序 (例如:Spring Boot项目),会用到这个特性,所以先给大家混个眼熟。

使用PM2管理非Node.js项目

命令行方式

PM2管理非Node.js最简单的方式是在 pm2 start xxx 这样启动的命令行中,加上 --interpreter 来指定解释执行器来达到执行非Node.js项目的目的,例如:

1
2
$ pm2 start my_app.py --interpreter '/usr/bin/python'
$ pm2 start my_app.bat --interpreter 'cmd.exe'

生态系统文件方式

上一节大概知道了pm2有一个生态系统文件,下面简单介绍一下如何使用生态文件系统配置的方式来指定我们的执行程序。

创建配置文件

使用如下命令即可生成一个简单的配置文件。

1
$ pm2 init simple

执行完毕后,生成的 ecosystem.config.js, 内容如下:

1
2
3
4
5
6
module.exports = {
apps : [{
name : "app1",
script : "./app.js"
}]
}

注意 :您如果要重新修改上述配置的文件名或者手动创建配置文件,则必须保证文件的后缀为 .config.js ,要不然PM2无法识别。

自定义编写配置文件

此处以执行 Spring Boot 项目为例来说明,更多的配置文件说明请查阅 官网文档

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
apps : [{
name : "app6",
script : "java.exe",
"args": [
"-jar",
"app6.jar"
],
"exec_interpreter": "",
"exec_mode": "fork"
}]
}

以上配置文件参数说明如下:

  • name 进程名称(显示在pm2 list命令中)
  • script 执行进程名称,如果需要执行PHP脚本则填写php解释器的路径,本文为java
  • args 传给执行进程的参数,多个参数以数组单元分割
  • exec_interpreter NodeJs解析器,本文不适用
  • exec_mode 执行模式[cluster|fork]这个针对NodeJs应用的配置,非NodeJs应用统一fork

启动服务

假设上面的配置文件我们命名为了 app6.config.js,则使用如下命令启动:

1
$ pm2 start app6.config.js


至此我们已经成功的使用PM2将 Spring Boot 项目管理起来了。

执行配置文件中的部分服务

细心的你是否发现了上面的配置文件中 app 的值是一个数组,这就意味着我们可以在一个配置文件中配置多个服务。假如我们的配置文件中有三个名字分别为 app1, app2, app3 的三个服务,当我们想启动部分服务时可以使用 --only 参数来完成。

启动 app1:

1
$ pm2 start ecosystem.config.js --only "app1"

启动 app1 和 app3:

1
$ pm2 start ecosystem.config.js --only "app1,app3"

注意: --only 参数只能用在 start/restart/stop/delete 这些子命令中。

切换运行环境

我们可以使用配置文件中的 env_* 选项来指定不同的环境变量,例如:

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
apps : [{
name : "app1",
script : "./app.js",
env_production: {
NODE_ENV: "production"
},
env_development: {
NODE_ENV: "development"
}
}]
}

运行时切换环境很简单,使用 --env [env name] 选项即可,例如:

1
2
$ pm2 start process.json --env production
$ pm2 restart process.json --env development

重要的一点

本章节仅仅是介绍了一个配置文件的皮毛。仅仅可以让你对配置文件有个简单的了解并且通过简单配置可以执行非Node.js的项目。但是PM2的配置文件的配置项很多,建议读者还是去 官网文档 看看都有那些配置项,这样能更好的帮助您定制化自己所期望的服务治理。

最后

如同在 PM2的特性 章节中所列出的一样,PM2还有很多特性是在本片文章中没有介绍的。如果你对PM2比较感兴趣,建议去 官方站点 翻阅相关资料。


欢迎关注我的公众号 须弥零一,跟我一起学习IT知识。


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !