【RabbitMQ 笔记】— 常见问题
何时该用 MQ
大致可以分为下面四种场景
- 削峰限流:当上游能力远大于下游处理能力
- 数据驱动的任务依赖:任务之间有一定的依赖关系
- 上游不关心下游执行结果:解耦
- 异步返回执行时间长:离线处理,或者跨公网调用等
不应该使用 MQ
- 上游实时关注执行结果
保证消息不丢失
以 RabbitMQ 为例
- 生产者开启 Publisher Confirm 机制:确保消息可靠到达 RabbitMQ
- 生产者使用 mandatory 参数或备用交换器确保消息路由到队里中
- 消息和队列开启持久化:RabbitMQ 服务器重启确保消息不丢失
- 消费者将 autoAck 设为 false, 使用手动确认
保证消息幂等
- 生产者:消息全局 ID,业务无关,比如 RabbitMQ 的 deliveryTag
- 消费端:消息带有业务唯一id,由消费者进行去重判断
削峰限流
为何需要削峰限流?
下游服务无法控制达到自己的流量,如果上游服务不限速,很可能把下游服务压垮。
能不能举个栗子?
比如秒杀业务:
上游发起下单操作
下游完成秒杀业务逻辑(库存检查,库存冻结,余额检查,余额冻结,订单生成,余额扣减,库存扣减,生成流水,余额解冻,库存解冻)
上游业务简单,每秒 1 万个请求,下游业务复杂,每秒只能处理 2 千个请求,如果上游不限速,那么很可能把下游压垮,引发雪崩
那如何解决雪崩呢?
上游限速发送
下游限速执行
如何缓冲流量?
使用 MQ 来做缓冲,并且消费者模式从推模式(push)改为拉模式(pull)。消费者根据自身的处理能力,每隔一段时间,或者每次拉去一定数量的消息。
如果消费者处理能力有限,MQ 队列中消息积压怎么办?
这就需要对消费端进行优化,比如批量写,来提升整体的吞吐量