先说我最近遇到的一件事。朋友公司的下单接口一到晚高峰就超时,他们把 MySQL 缓存、索引、连接池全调了一遍,还是不行。我看了代码之后发现,一个下单请求里居然同步调了扣库存、发短信、通知配送三个接口——最慢的那个下游直接拖垮了整个下单体验。我说:你缺的不是缓存,是消息队列。
很多人听到“消息队列”四个字就觉得高深,觉得它是大厂才玩的东西。其实说白了,消息队列就是一个专门用来暂存消息、再按节奏投递给消费者的中间件。RabbitMQ 是这个领域里最经典、也最好上手的开源实现之一。本文会从“消息队列解决什么问题”开始,带你把 RabbitMQ 的核心概念搞懂,然后用 Spring Boot 亲手写一个能收发消息的小项目,最后把重复消费、消息丢失、消息堆积这几个真正影响上线的坑一次性说清楚。零基础可以直接跟下来,有一点基础的人也能在确认机制、死信队列这些环节找到新东西。
1. 为什么你的系统需要消息队列:一次线上超时事故换来的教训
1.1 同步调用的“连锁超时”
先把刚才那个场景展开。下单接口的代码逻辑大概是这样的:
java复制// 伪代码:同步调用三个服务
Order order = createOrder(userId, goodsId); // 1. 创建订单
boolean stockResult = stockService.deduct(order); // 2. 扣减库存,RPC调用
boolean smsResult = smsService.send(order); // 3. 发短信,RPC调用
boolean deliveryResult = deliveryService.notify(order); // 4. 通知配送,RPC调用
return Result.success(order);
这段代码在低流量阶段没有任何问题。可一旦流量上来,问题就暴露了:
- 接口响应时间等于四个服务耗时的总和。扣库存 200ms、发短信 500ms、通知配送 800ms,订单自己 100ms,总计就是 1.6 秒。
- 任何一个下游抖动,比如短信通道偶尔 3 秒才返回,用户感知到的就是下单按钮转圈。
- 下游服务一旦不可用,接口直接失败,订单都创建不了。
这就
