【架构师面试-消息队列-6】-MQ消息的积压与过期解决方案

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)。

【架构师面试-消息队列-6】-MQ消息的积压与过期解决方案

消息成为死信的三种情况

1. 队列消息长度到达限制;

2. 消费者拒接消息(basicNack),并且不把消息重新放回源队列,requeue=false;

3. 源队列存在消息过期设置,消息到达超时时间未被消费;

设置死信队列绑定死信交换机

给队列设置参数: x-dead-letter-exchange 和 x-dead-letter-routing-key

【架构师面试-消息队列-6】-MQ消息的积压与过期解决方案

 

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 消息队列,重建之后绑定死信交换机

【架构师面试-消息队列-6】-MQ消息的积压与过期解决方案

5. 向消息队列 order.B 中发送消息【消息队列order.B中的消息失效时间为5秒】

【架构师面试-消息队列-6】-MQ消息的积压与过期解决方案6. 等待5秒,消息队列order.B中的消息进入死信队列

【架构师面试-消息队列-6】-MQ消息的积压与过期解决方案

4:小结

1. 死信交换机和死信队列和普通的没有区别

2. 当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列

3. 消息成为死信的三种情况:

        队列消息长度到达限制;

        消费者拒接消费消息,并且不重回队列;

        原队列存在消息过期设置,消息到达超时时间未被消费;

上一篇:Apache ShardingSphere 5.0.0 内核优化及升级指南


下一篇:排序sql注入问题