消息队列
问题
消息队列在后端架构中起什么作用?常见的消息队列有哪些?前端需要了解吗?
答案
消息队列的作用
| 作用 | 说明 | 示例 |
|---|---|---|
| 异步解耦 | 生产者不需要等消费者处理完 | 下单后异步发短信通知 |
| 削峰填谷 | 流量高峰时积压在队列中,慢慢消费 | 秒杀场景 |
| 可靠投递 | 消息持久化,不怕服务重启丢失 | 支付回调 |
| 广播 | 一条消息多个消费者处理 | 订单创建后,库存、物流、通知各自处理 |
常见消息队列对比
| 维度 | RabbitMQ | Kafka | Redis Pub/Sub | BullMQ |
|---|---|---|---|---|
| 定位 | 通用消息代理 | 高吞吐流处理 | 轻量发布订阅 | Node.js 任务队列 |
| 吞吐量 | 万级/s | 百万级/s | 万级/s | 万级/s |
| 持久化 | ✅ | ✅ | ❌ | ✅(Redis) |
| 消息确认 | ✅ | ✅ | ❌ | ✅ |
| 适用 | 企业应用 | 大数据/日志 | 简单广播 | Node.js 后台任务 |
BullMQ 实战(Node.js 最常用)
queue-setup.ts
import { Queue, Worker } from 'bullmq';
import IORedis from 'ioredis';
const connection = new IORedis({ host: 'localhost', port: 6379 });
// 创建队列
const emailQueue = new Queue('email', { connection });
// 生产者:添加任务
await emailQueue.add('send-welcome', {
to: 'user@example.com',
subject: '欢迎注册',
template: 'welcome',
});
// 消费者:处理任务
const worker = new Worker('email', async (job) => {
console.log(`Processing job ${job.id}: ${job.name}`);
await sendEmail(job.data);
}, { connection, concurrency: 5 });
worker.on('completed', (job) => {
console.log(`Job ${job.id} completed`);
});
worker.on('failed', (job, err) => {
console.error(`Job ${job?.id} failed:`, err.message);
});
前端相关的消息队列场景
frontend-scenarios.ts
const frontendRelatedScenarios = {
// 1. 消息推送:后端通过队列处理后,推送到前端 WebSocket
realtimeNotification: '订单状态变更 → 队列 → WebSocket → 前端更新',
// 2. 文件处理:前端上传文件后,后端异步处理
fileProcessing: '上传图片 → 队列 → 压缩/裁剪 → 通知前端完成',
// 3. SSE 推送:AI 聊天场景,消息通过队列串联
aiChat: '用户提问 → 队列 → AI 处理 → SSE 流式推送到前端',
// 4. 导出任务:前端触发、后端异步生成
exportTask: '点击导出 → 队列 → 生成 Excel → 通知前端下载',
};
常见面试问题
Q1: 消息丢失怎么办?
答案:
三个环节保证不丢消息:
- 生产者确认:发送后等待队列 ACK
- 队列持久化:消息写入磁盘
- 消费者确认:处理完后手动 ACK,失败自动重试
Q2: 消息重复消费怎么办?
答案:
消费者实现幂等性:
- 用消息 ID 做去重(数据库唯一索引、Redis SetNX)
- 业务层幂等(如支付接口根据订单号幂等)
Q3: 死信队列是什么?
答案:
消费失败多次后,消息会进入死信队列(Dead Letter Queue),便于人工排查和重新处理,不阻塞正常队列。
Q4: Kafka 和 RabbitMQ 怎么选?
答案:
- RabbitMQ:对消息可靠性要求高、需要复杂路由、消息量不大
- Kafka:超高吞吐量、日志/事件流处理、需要消息回溯
Q5: 前端工程师需要了解消息队列吗?
答案:
需要了解基本概念,原因:
- BFF 层可能需要与队列交互
- 理解后端架构有助于排查问题
- Node.js 后端常用 BullMQ 处理异步任务
- 实时功能的实现链路通常涉及消息队列
相关链接
- WebSocket 与 SSE - 前端实时通信
- 设计实时通讯系统 - IM 系统设计