1. PM2 Cluster 模式概念
- PM2 会根据 CPU 核心数自动启动多个 Node.js 进程(Worker),每个进程都是独立的事件循环。
- 每个 Worker 进程可以独立连接 RabbitMQ 并消费队列。
- RabbitMQ 会将队列消息 公平分发给不同进程,保证不会重复投递。
优势:无需手动管理 cluster,自动利用多核 CPU,实现高并发处理。
2. 消息位置(delivery tag)在 PM2 Cluster 下的处理
-
每个 Worker 进程独立 channel:delivery tag 是 channel 内部唯一标识。
-
不同进程的 delivery tag 相互独立:不会冲突。
-
ack 消息:处理完成后每个 Worker 单独 ack,不影响其他进程。
-
顺序敏感任务:
-
多进程消费时,队列内部顺序在不同进程之间不保证。
-
解决方案:
- 对顺序敏感的任务使用单独队列。
- 或在 Worker 内部使用子队列顺序处理。
-
3. 使用 PM2 Cluster + RabbitMQ 的示例
(1)安装依赖
npm install amqplib
npm install pm2 -g
(2)消费者示例
javascript
// consumer.js
const amqp = require('amqplib');
async function startConsumer() {
const conn = await amqp.connect('amqp://localhost'); // 集群模式可使用 ['amqp://node1', 'amqp://node2']
const channel = await conn.createChannel();
const queue = 'taskQueue';
// Quorum Queue 提高可靠性
await channel.assertQueue(queue, { durable: true, arguments: { 'x-queue-type': 'quorum' } });
channel.prefetch(1);
channel.consume(queue, async (msg) => {
const task = JSON.parse(msg.content.toString());
console.log(`Worker PID ${process.pid} processing task ${task.id}`);
try {
// 模拟任务处理
await new Promise(resolve => setTimeout(resolve, 100));
// ack 消息
channel.ack(msg);
} catch (err) {
console.error(err);
// 不 ack,消息自动重试或进入死信队列
}
}, { noAck: false });
}
startConsumer();
(3)使用 PM2 启动 Cluster 模式
arduino
pm2 start consumer.js -i max
说明:
-i max
表示 PM2 根据 CPU 核心数自动启动 Worker。- 每个 Worker 都会独立连接 RabbitMQ 并消费队列。
- RabbitMQ 会将消息公平分发给 Worker,不会重复或冲突。
- delivery tag 在每个 Worker 内独立管理,安全可靠。
4. 多进程分发与汇总策略
-
主任务拆分
- 将任务拆分为子任务 → 发送到队列。
-
Worker 并行处理
- PM2 启动多个 Worker,每个 Worker 独立消费队列消息。
-
结果汇总
- Worker 处理完成后,将结果写入数据库或发送到汇总队列。
- 使用幂等操作避免重复更新。
5. 注意事项
-
幂等性
- 每条消息加唯一 ID,避免重复处理或更新全局状态。
-
顺序敏感任务
- 需要单独队列处理,或在 Worker 内部使用子队列顺序消费。
-
资源监控
- 监控队列长度、Worker 消费速率、CPU/内存使用。
-
消息确认机制
- 成功处理后
ack
,失败进入死信队列,保证可靠性。
- 成功处理后
6. 总结
-
PM2 Cluster 模式无需手动管理 cluster,自动利用多核 CPU。
-
RabbitMQ 消息位置(delivery tag)在每个 Worker 内独立管理,不会冲突。
-
消息队列在集群模式下可靠性由 Quorum Queue 保证,多进程并行消费通过 PM2 Cluster 实现。
-
核心原则:
- Worker 独立 channel。
- 幂等处理。
- 顺序敏感任务单独队列或内部顺序消费。
- 汇总结果可统一写入数据库或缓存。
本文部分内容借助 AI 辅助生成,并由作者整理审核。