Node.js集群与PM2进程管理
2025.06.25
8 min
3.0k 字
// 目录 · contents
前言
Node.js是单线程运行的,无法充分利用多核CPU。Cluster模块允许创建多个工作进程,共享同一个端口,从而实现多核利用和高可用。PM2是最流行的Node.js进程管理器,提供了集群管理、监控、日志和零停机部署等功能。本文将深入分析这两者的原理和使用方法。
Cluster模块原理
graph TB
subgraph "Cluster Architecture"
MASTER[Master Process<br>pid: 1234] --> |fork| W1[Worker 1<br>pid: 1235]
MASTER --> |fork| W2[Worker 2<br>pid: 1236]
MASTER --> |fork| W3[Worker 3<br>pid: 1237]
MASTER --> |fork| W4[Worker 4<br>pid: 1238]
CLIENT[Client Requests] --> |port 3000| MASTER
MASTER --> |Round-Robin| W1
MASTER --> |Round-Robin| W2
MASTER --> |Round-Robin| W3
MASTER --> |Round-Robin| W4
end
Master进程通过child_process.fork()创建Worker进程。在Linux上,默认使用Round-Robin负载均衡(轮询分发请求)。
基础使用
1 | |
Master-Worker通信
1 | |
优雅关闭(Graceful Shutdown)
1 | |
零停机重启
sequenceDiagram
participant M as Master
participant W1 as Worker 1 (旧)
participant W2 as Worker 2 (旧)
participant W3 as Worker 1 (新)
participant W4 as Worker 2 (新)
Note over M: 收到重启信号
M->>W1: disconnect()
Note over W1: 停止接受新连接<br>完成现有请求
M->>W3: fork() 新Worker
Note over W3: 启动并开始接受请求
W1->>M: exit
Note over W1: 旧Worker退出
M->>W2: disconnect()
M->>W4: fork() 新Worker
Note over W4: 启动并开始接受请求
W2->>M: exit
Note over M: 所有旧Worker已替换<br>零停机完成
1 | |
PM2进程管理器
安装和基本使用
1 | |
生态系统配置文件
1 | |
1 | |
PM2零停机部署
flowchart TB
TRIGGER[触发部署] --> PULL[拉取最新代码]
PULL --> INSTALL[安装依赖]
INSTALL --> BUILD[构建项目]
BUILD --> RELOAD[PM2 reload]
subgraph "PM2 Reload过程"
RELOAD --> NEW1[启动新Worker 1]
NEW1 --> |就绪| KILL1[关闭旧Worker 1]
KILL1 --> NEW2[启动新Worker 2]
NEW2 --> |就绪| KILL2[关闭旧Worker 2]
KILL2 --> DONE[完成]
end
Note over RELOAD,DONE: 整个过程不中断服务
1 | |
在应用中配合PM2实现优雅关闭
1 | |
PM2监控与日志
1 | |
1 | |
PM2开机自启
1 | |
负载均衡策略
graph TB
subgraph "Round-Robin (Linux默认)"
RR_M[Master] -->|请求1| RR_W1[Worker 1]
RR_M -->|请求2| RR_W2[Worker 2]
RR_M -->|请求3| RR_W3[Worker 3]
RR_M -->|请求4| RR_W1
end
subgraph "Nginx反向代理 (推荐)"
NGINX[Nginx] -->|upstream| N1[Node :3001]
NGINX -->|upstream| N2[Node :3002]
NGINX -->|upstream| N3[Node :3003]
NGINX -->|upstream| N4[Node :3004]
end
1 | |
Cluster模式下的共享状态
graph TB
subgraph "问题:每个Worker有自己的内存"
W1[Worker 1<br>session: {a:1}]
W2[Worker 2<br>session: {}]
W3[Worker 3<br>session: {}]
NOTE[用户登录在Worker 1<br>下次请求到Worker 2时Session丢失]
end
subgraph "解决方案:外部存储"
WA[Worker 1] --> REDIS[(Redis)]
WB[Worker 2] --> REDIS
WC[Worker 3] --> REDIS
NOTE2[所有Worker共享同一个Redis中的Session]
end
1 | |
总结
Node.js集群和PM2的核心要点:
- Cluster模块:通过fork创建多个Worker进程,共享端口,利用多核CPU
- 负载均衡:Linux默认Round-Robin,生产环境建议Nginx反向代理
- PM2集群模式:
pm2 start app.js -i max一键启动集群 - 零停机部署:
pm2 reload逐个重启Worker,不中断服务 - 优雅关闭:监听SIGTERM信号,先停止接受新连接,等待现有请求完成后退出
- 共享状态:使用Redis等外部存储解决多进程间状态共享问题
- 监控:PM2 monit实时监控,自定义指标和动作
在生产环境中,PM2 + Nginx的组合是Node.js部署的常见方案,能够提供高可用性和良好的性能。
$ echo "comments" · 评论