rabbitmq 怎么保证消息可靠性?

79 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 29 天,点击查看活动详情

1 前言

MQ 有系统异步、流量削峰、应用解耦等作用,在分布式系统的开发过程中,为了提高性能而引入消息,带来的便利能缓解很大的压力。但是引入 mq 会导致系统的可用性降低、复杂度提升,但是更大的问题则是如何保证 mq 消息的可靠性,在本文中将以 rabbitmq 为例讲述如何保证消息的可靠性。

2 MQ 可靠性分析

mq 发送消息的过程是发送者发送消息到 broker, broker 包括(交换机-绑定-队列), 由此我们可以知道消息发送的可靠性可以分为: 发送方发送的可靠性、消息存放的可靠性、以及消息接收的可靠性。

3 消息发送可靠性

在发送方发送消息时,需要开启信道(即 channel,也可以理解为连接 )的 confirm 机制,所有的信道在发送消息时都会分配一个唯一的消息 ID。一旦消息被投送到 队列中或者持久化到磁盘中,信道会发送一个消息给生产者,如果 broker 内部发生错误或者其他原因导致消息没有成功发送,则会发送 nack 给消息的生产者。所有的消息都会被 confirm(即 ack) 或者是 nack 一次,但是对确认消息的快慢没有做保证。

发送方确认模式是异步操作,生产者应用程序在等待确认的同时,也可以继续发送消息,当确认消息达到生产者后会触发回调方法。ConfirmCallback 接口发送成功的回调,ReturnCallback 是消息发送失败时的回调。

4 消息消费的可靠性

消息消费者在消费消息时,需要给 broker 发送 ack 消息,当 broker 收到确认消息后,才会从内存或者磁盘中将消息移除。rabbitmq 在消息消费时不要采用自动确认消息的方式,而是待业务处理完成后进行手动确认消息,这样的操作即可保证消息消费的可靠性。

此外,rabbitmq 对没有确认的消息不会设置超时时间,它判断消息是否需要重新投递的唯一标识就是消费者下线或者因为网络原因断开,这样的设计可以保证数据的最终一致性。

如果消费者返回 ack 之前断开了连接,那么 rabbitmq 可能会重新进行消息的投递,此时需要消息消费可能会出现重复的情况,因此需要在消息发送时,对每条消息设置唯一的业务 id, 在处理业务时需要进行判断操作。

5 消息的存储可靠性

消息存储的可靠性就相对消息的发送和消费来说就比较简单了,主要就是在创建队列机时,需要开启数据的持久化操作,即 durable 参数,当该参数开启后,则可以保证消息在 broker 的存储可靠性,当服务重启后,消息没有丢失,还可以继续提供有效服务。

6 总结

在本文中,主要分享了 rabbitmq 消息可靠性的知识,从消息的发送、存储以及消费的角度阐释了如何保证消息的可靠性,在后续的文章中将继续分享有关 rabbitmq 的实践经验。