为什么 Node 应用要用 PM2 来跑?

文章介绍了pm2作为Node.js应用的进程管理工具,如何解决应用崩溃自动重启、日志管理和负载均衡等问题。通过pm2,可以实现日志输出到文件、多进程运行以利用多核CPU、监控应用性能,并通过配置文件自动化管理多个应用。此外,还提及了pm2的付费功能pm2plus用于在线监控。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在服务器上,我们不会直接跑 node,而会用 pm2 来跑。

为什么要用 pm2 呢?它解决了啥问题?

想一下:

  • 如果你的 node 应用跑的时候突然抛了个错,崩溃了,是不是需要重新跑起来?这时候是不是就需要另一个进程来自动做重启这件事情?

  • node 应用的日志默认输出在控制台,如果想输出到不同的日志文件,是不是可以让另一个进程获取 node 应用的输出,然后写文件来实现?

  • node 是单线程的,而机器是多个 cpu 的,为了充分利用 cpu 的能力,我们会用多个进程来跑 node 应用,这种通用逻辑是不是也可以放到一个单独进程里来实现?

  • node 运行时的 cpu、内存等资源的占用,是不是需要监控?这时候是不是可以让另一个进程来做?

线上的 node 应用不只是跑起来就行了,还要做自动重启、日志、多进程、监控这些事情。

而这些事情,都可以用 pm2 来做。

pm2 是 process manager,进程管理,它是第二个大版本,和前一个版本差异很大,所以叫 pm2.

pm2 的主要功能就是进程管理、日志管理、负载均衡、性能监控这些。

我们分别来看一下:

首先安装 pm2:

npm install -g pm2

然后跑一个 node 应用,我这里跑一个 Nest.js 的应用:

直接 node 跑是这样的,日志打印在控制台:

2de82589353d99b222cc9ce99a22afcc.png

而用 pm2 的话,就可以这样跑:

pm2 start ./dist/main.js

它会把这个 node 进程跑起来,然后管理起来:

6cafd924604a0a587a872731c8e4eda3.png

管理起来之后,就有我们上面说的那些功能了,比如自动重启、日志管理、性能监控等。

首先看下日志,执行

pm2 logs
4c74f38713b911f50895603b55ca3eeb.png
i

可以看到 pm2 会把所有进程的日志打印出来,通过前面的“进程id|进程名字”来区分,比如 0|main。

而且,它会把它写到日志文件里,在 ~/.pm2/logs 下,以“进程名-out.log”和“进程名-error.log”分别保存不同进程的日志:

46af1a8693054f9ef63767d4d815d62e.png

比如 main-out.log 里保存了 main 进程的正常日志,而 main-error.log 里保存了它的报错日志:

a510bcb0b4cb5de71216dfc5142e171a.png

我们再跑一个进程试试:

668368f384d3b5242a2ed85c6d8e9c0c.png

现在有两个进程了,pm2 logs 可以看到这两个进程的日志:

df1baf4fda2ac2872d3bc0dc0661aec9.png

也可以

pm2 logs 进程名/进程id

这样查看单个进程的日志:

adf9278cf5893c9960ad3efcb770d0ca.png

这就是 pm2 的日志管理的功能。

进程管理的话就是可以手动启动、重启、停止某个进程,而且崩溃了会自动重启,也可以定时自动重启。

只需要 pm2 start 的时候带上几个选项就好了:

超过 200M 内存自动重启:

pm2 start xxx --max-memory-restart 200M

从 2s 开始每 3s 重启一次:

pm2 start xxx --cron-restart "2/3 * * * * *"

当文件内容改变自动重启:

pm2 start xxx --watch

不自动重启:

pm2 start xxx --no-autorestart

我们分别试一下:

把之前的进程删掉:

pm2 delete 0
0ab1e9b0e9d4544fabce42376c651757.png

我们指定 1k 内存就重启:

pm2 start xxx --max-memory-restart 1K
d1210993d83725c038ee317296c9165f.png

然后在 nest 代码里用超过 1k 的内存:

39a697906bb8ebd9720eac852776e070.png

先把之前的日志清空,使用 pm2 flush 或者 pm2 flush 进程名|id

954b3fe2ccb63c55cbb01181c0246652.png

确实清空了:

f595601c9b2d18cb7573680b5a166810.png

访问下这个 controller:

dcdb840cff4a126dc01d849113ce8706.png

查看 main 进程的前 100 行日志:

pm2 logs main --lines 100
0e63f3793d3e24ac8da8412a1771c73b.png

明显看到重启了。

这是超过内存的自动重启。

崩溃的自动重启、定时自动重启、文件变动自动重启等也是类似 。

我们前面用到的 pm2 start、pm2 stop、pm2 restart、pm2 delete 等就是进程管理的功能。

再就是负载均衡,node 应用是单进程的,而为了充分利用多核 cpu,我们会使用多进程来提高性能。

node 提供的 cluster 模块就是做这个的,pm2 就是基于这个实现了负载均衡。

我们只要启动进程的时候加上 -i num 就是启动 num 个进程做负载均衡的意思。

pm2 start app.js -i max 
pm2 start app.js -i 0

这俩是启动 cpu 数量的进程。

用多进程的方式跑 nest 应用:

e6718d4e864050423b8f4ba102505241.png

可以看到启动了 8 个进程,因为我是 8 核 cpu。

跑起来之后,还可以动态调整进程数,通过 pm2 scale:

pm2 scale main 3

我把 main 的集群调整为 3 个进程:

b56732a54bbb7abcb21d77f4e3cb99e8.png

可以看到 pm2 删除了 5 个,留下了 3 个。

pm2 scale main +3

我又加了 3 个,现在变成了 6 个:

db1242f6d4f99ce6a41ff50ff37de628.png

可以动态伸缩进程的数量,pm2 会把请求分配到不同进程上去。

这就是负载均衡功能。

此外,还有个性能监控功能,执行 pm2 monit:

pm2 monit
1cb06874d773e6544100c01910aad2f5.gif

可以看到不同进程的 cpu 和内存占用情况。

大概就是这些功能,但是当进程多了之后,难道都要手动通过命令行来启动么?

肯定不会每次都敲一遍。

pm2 支持配置文件的方式启动多个应用。

执行 pm2 ecosystem,会创建一个配置文件:

e07a7b365dc34af1a197da2e124ea3c1.png

apps 部分就是配置应用的,scripts 就是应用的启动路径:

25f9f498b98d0eea13cde0372185d208.png

它可以指定的配置非常多,基本就是命令行有啥选项,这里就有啥属性:

a249ed0a3c86c6514c7ddcbf0da3e93b.png

然后 pm2 start ecosystem.config.js 就可以批量跑一批应用。

就相当于 pm2 根据配置文件自动执行这些命令,不用我们手动敲了。

这样,我们就可以把启动的选项保存在配置文件里。

最后,还有个 pm2 plus,这个是收费功能,看看就行:

访问 pm2 的网站,登录,创建 bucket:

fe05050739d753a13ef21bea7345a29e.png

然后在本地执行 pm2 link xxx xxx,把本地的 pm2 和那个网站关联起来:

871567bb3e73183b9a302e6e34b4cfa9.png

再执行 pm2 plus 就会打开 bucket 对应的网页:

f102c8dd7f250037c39d9f894b935cde.png

可以在线监控你的应用:

514b6e02b315a9eff504e61554e5d3b4.png

下面这些 plus 的功能都是收费的:

c2b6edf2b6857cb27293e8f63103fdea.png

一般也不需要用,用免费的本地功能就好了。

总结

服务器上的 node 应用需要用 pm2 的日志管理、进程管理、负载均衡、性能监控等功能。

分别对应 pm2 logs、pm2 start/restart/stop/delte、pm2 start -i、pm2 monit 等命令。

多个应用或者想把启动选项保存下来的时候,可以通过 ecosystem 配置文件,批量启动一系列应用。

不管是出于稳定性、性能还是可观测性等目的,pm2 都是必不可少的。

82eb65387a4c9c9366b7ce0c9f4b0e6d.png

往期推荐

眨个眼就学会了 Pixi.js

369ada60e8db19a3a207f2723f4fd9a3.png

再也不用手动改package.json的版本号

bb8c4db1a1bf4feebcb7a3f4c3e18834.png

埋点SDK,我是如何让甲方的页面卡顿10s+

ca7976dfde5f92916a82c68f16cb51cf.png

最后

  • 欢迎加我微信,拉你进技术群,长期交流学习...

  • 欢迎关注「前端Q」,认真学前端,做个专业的技术人...

45ab4a56b9d1f17b677fbb9ad4c86bb8.jpeg

3ce2d6324695d267100f6b4c80c06b06.png

点个在看支持我吧

fa1a6093631abb8c228e3da8270dcc9c.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值