消息队列学习记录
RabbitMQ如何保证消息的可靠性?
从3个层面上考虑,包括生产端,Broker端,消费端。
生产端
使用消息确认机制ack
- 生产者端在发生消息后可以注册一个回调函数,用于监听消息是否成功送达Broker。
- 如果消息成功写入队列,RabbMQ会返回一个ack;
- 如果失败(如队列不存在、交换机不可达),会返回nack。
Broker端
1.持久化
对象 | 属性 | 说明 |
---|---|---|
Queue | durable=true | 队列在服务器重启后仍存在 |
Exchange | durable=true | 交换机持久化 |
Message | deliveryMode=2 | 消息持久化(1=非持久化,2=持久化) |
注意:即使设置了持久化,也只能防止 服务器宕机 的消息丢失,不能防止 未被消费就删除 的情况。
2.镜像队列(集群)
- RabbitMQ集群中使用镜像队列方式,将队列同步到多个节点,这样即使某个节点宕机,其他节点仍可处理该队列的消息,保障高可用。
消费端
1.手动ack
- 消费者处理完消息后,手动发送basicAck告诉RabbitMQ已经处理完;
- 如果未确认RabbitMQ不会删除消息;
- 如果消费程序崩溃,RabbiMQ会将消息重新发送给其他消费者(或者当前重启的消费者)。
2.消息重试与死信队列(DLX)
- 若消息消费失败,可以通过配置死信队列将其转发,便于后续排查或如果处理
- 可以结合重试机制避免消息丢失
死信队列
“死信队列”是 RabbitMQ 中的一种机制,用于处理无法被正常消费的消息,可以防止消息丢失并实现异常追踪、告警处理、消息重发、补偿机制。
- 消息被拒绝(rejected),并且
requeue=false
- 消息过期(TTL 到期)
- 队列已满,无法继续投递消息
那如何保证消息不重复消费呢?
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 dmw's blog!
评论