导入依赖:
后续延迟队列优化用Springboot整合,先理解死信队列
死信队列
由于特定原因导致队列中的消息不能被消费,这样的消息如果没有后续处理就可以放入死信队列中,例如一个订单如果超时未被支付从而自动失效,就将这个订单放到死信队列中。(死信队列中的消息是可以被消费的)
死信队列产生的原因
消息TTL过期
就是在规定的时间内消息没有被消费,(和延迟队列不同,延迟队列时表示到达时间消息才可以被消费)
在生产者代码中设置消息过期时间:
修改队列参数argument的特殊属性:
模拟代码:
消费者1
生产者
消费者2
队列达到了最大长度
将RabbiMQ的队列的argument属性的键设置为 x-max-length 表示队列可以容纳的最大条数
消息被拒绝
将自动应答设为false
在消费者调一个Channel.basicReject,设置参数requeue为false,表示不重新排队,将消息丢到死信队列
延迟队列优化
延迟队列就是讲一个消息延迟发送,例如消息在队列中10s后才能被取出,可以通过RabbitMQ的插件或者死信队列来实现
用死信队列实现延迟队列的思路:
在于死信队列绑定的普通队列不设置消费者,利用TTL延迟消息,当TTL时间过期后,到达死信队列被消费这样就形成一个延迟队列。
延迟队列的使用场景:①典型的就是流量削峰,对于不重要的消息,可以延迟消费,有助于减轻数据库的压力,强化分布式系统的高可用和并发性能。②还可以实现一个消息提醒,例如用户三天未登录发送一个消息提醒。
在实际生产中可能存在很多不同的延迟时间要求,不可能每一个延迟要求就创造一个队列,我们可以用生产者实现延迟信息,而队列不设置TTL就可以根据生产的延迟消息进行延迟发送。
但是此方法虽然实现了一个队列就可以转发不同延时时间的消息,但是有缺陷,队列中的消息是排队发送的,也就是说如果我第一条消息发送20s延时,接着第二条消息发送2s延时。最后却是20s消息先消费,而2s消息后消费,因为RabbitMQ在检测一条消息时发生了20s的阻塞。如下:
可以通过RabbitMQ的插件实现延时队列,此方法没有这缺陷
从官网上下载对应版本的延迟插件,下载后如图:交换机类型会多出一个 x-delayed-message
在我们自定义的交换机中,这是一种新的交换机类型,该类型消息支持延迟投递机制,消息传递后并不会立即投递到目标队列中,而是存储在mnesia(一个分布式数据系统)表中,当达到投递时间时,才会投递到目标队列中。
代码实例:
配置类:
生产者:
消费者: