1:消息积压
场景
线上故障,几千万条数据在MQ里积压了7-8个小时。
这时,怎么处理呢?修复consumer端的BUG,然后等待8个小时消费完毕吗?肯定不行!一个消费者一秒是1000条,一秒3个消费者是3000条,一分钟是18万条,1000多万条。 如果你积压了上千万数据,即使消费者恢复,也需要2小时以上才能恢复。
解决方案
临时扩容,加快消费速度
1. 先修复consumer的问题,确保其恢复消费速度,然后将现有consumer都停掉。
2. 临时建立好原先10倍或者20倍的queue数量
3. 然后写一个临时分发消息的consumer程序,这个程序部署上去消费积压的消息,消费之后不做耗时处理,直接均匀轮询写入临时建好分10数量的queue里面。
4. 紧接着征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的消息。
5. 这种做法相当于临时将queue资源和consumer资源扩大10倍,以正常速度的10倍来消费消息。
6. 等快速消费完了之后,恢复原来的部署架构,重新用原来的consumer机器来消费消息。
2:消息过期
消息过期、丢失,发送失败如何处理?任由消息消失?
死信队列:当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DeadLetter Exchange(死信交换机 简写:DLX)。
消息成为死信的三种情况
1. 队列消息长度到达限制;
2. 消费者拒接消息(basicNack),并且不把消息重新放回源队列,requeue=false;
3. 源队列存在消息过期设置,消息到达超时时间未被消费;
设置死信队列绑定死信交换机
给队列设置参数: x-dead-letter-exchange 和 x-dead-letter-routing-key
3:死信队列案例
目标
演示消息队列中消息超时失效
实现步骤
1. 在RabbitMQ管理控制台中,创建死信队列 deadQueue
2. 在RabbitMQ管理控制台中,创建死信交换机 deadExchange
3. 死信队列绑定死信交换机,路由键为 order.dead
4. 消息队列order.B绑定死信交换机
5. 向消息队列 order.B 中发送消息【消息队列order.B中的消息失效时间为5秒】
6. 在RabbitMQ管理控制台中,将消息队列 order.B 绑定到交换机 order_exchange 上
7. 等待5秒,消息队列order.B中的消息进入死信队列
实现过程
1. 在RabbitMQ管理控制台中,创建死信队列 deadQueue
2. 在RabbitMQ管理控制台中,创建死信交换机 deadExchange
3. 死信队列绑定死信交换机,路由键为 order.dead
4. 删除 order.B 消息队列,重建之后绑定死信交换机
5. 向消息队列 order.B 中发送消息【消息队列order.B中的消息失效时间为5秒】
6. 等待5秒,消息队列order.B中的消息进入死信队列
4:小结
1. 死信交换机和死信队列和普通的没有区别
2. 当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列
3. 消息成为死信的三种情况:
队列消息长度到达限制;
消费者拒接消费消息,并且不重回队列;
原队列存在消息过期设置,消息到达超时时间未被消费;