前言
消息队列(MQ)是分布式系统中不可或缺的技术之一。
对很多小伙伴来说,刚接触MQ时,可能觉得它只是个“传话工具”,但用着用着,你会发现它简直是系统的“润滑剂”。
无论是解耦、削峰,还是异步任务处理,都离不开MQ的身影。
下面我结合实际场景,从简单到复杂,逐一拆解MQ的10种经典使用方式,希望对你会有所帮助。
1. 异步处理:让系统轻松一点
场景
小伙伴们是不是经常遇到这样的情况:用户提交一个操作,比如下单,然后要发送短信通知。
如果直接在主流程里调用短信接口,一旦短信服务响应慢,就会拖累整个操作。
用户等得不耐烦,心态直接崩了。
解决方案
用MQ,把非关键流程抽出来异步处理。下单时,直接把“发短信”这件事丢给MQ,订单服务就能立刻响应用户,而短信的事情让MQ和消费者去搞定。
示例代码
// 订单服务:生产者
Order order = createOrder(); // 订单生成逻辑
rabbitTemplate.convertAndSend("order_exchange", "order_key", order);
System.out.println("订单已生成,发短信任务交给MQ");
// 短信服务:消费者
@RabbitListener(queues = "sms_queue")
public void sendSms(Order order) {
System.out.println("发送短信,订单ID:" + order.getId());
// 调用短信服务接口
}
深度解析
这种方式的好处是:主流程解耦,不受慢服务的拖累。订单服务只管自己的事,短信服务挂了也没关系,MQ会把消息暂存,等短信服务恢复后继续处理。
2. 流量削峰:稳住系统别崩
场景
每年的“双十一”电商大促,用户秒杀商品时一窝蜂冲进来。
突然涌入的高并发请求,不仅会压垮应用服务,还会直接让数据库“趴窝”。
解决方案
秒杀请求先写入MQ,后端服务以稳定的速度从MQ中消费消息,处理订单。
这样既能避免系统被瞬时流量压垮,还能提升处理的平稳性。
示例代码
// 用户提交秒杀请求:生产者
rabbitTemplate.convertAndSend("seckill_exchange", "seckill_key", userRequest);
System.out.println("用户秒杀请求已进入队列");
// 秒杀服务:消费者
@RabbitListener(queues = "seckill_queue")
public void processSeckill(UserRequest request) {
System.out.println("处理秒杀请求,用户ID:" + request.getUserId());
// 执行秒杀逻辑
}
深度解析
MQ在这里相当于一个缓冲池,把瞬时流量均匀分布到一段时间内处理。系统稳定性提升,用户体验更好。
3. 服务解耦:减少相互牵制
场景
比如一个订单系统需要通知库存系统扣减库存,