RabbitMQ学习笔记 - 消息传输保障

参考:<>

消息可靠传输一般是业务系统接入消息中间件时首要考虑的问题,一般消息中间件的消息传输保障分为三个层级:

  • At most once:最多一次。消息可能会丢失,但绝不会重复传输。
  • At least once:最少一次。消息绝不会丢失,但可能会重复传输。
  • Exactly once:恰好一次。每条消息肯定会被传输一次且仅传输一次。

RabbitMQ支持其中的“最多一次”和“最少一次”。

1. 最少一次

“最少一次”投递实现需要考虑以下这个几个方面的内容:

  • 消息生产者需要开启 事务机制 或者 publisher confirm (发送方确认)机制,以确保消息可以可靠地传输到 RabbitMQ中。
  • 消息生产者需要配合使用 mandatory 参数或者 备份交换器 来确保消息能够从交换器路由到队列中,进而能够保存下来而不会被丢弃。
  • 消息和队列都需要进行持久化处理,以确保 RabbitMQ 服务器在遇到异常情况时不会造成消息丢失。
  • 消费者在消费消息的同时需要将 autoAck 设置为 false,然后通过手动确认的方式去确认已经正确消费的消息,以避免在消费端引起不必要的消息丢失。

2. 最多一次

”最多一次“的方式就无须考虑以上那些方面,生产者随意发送,消费者随意消费,不过这样很难确保消息不会丢失。

3. 恰好一次

"恰好一次"是 RabbitMQ 目前无法保障的。

考虑以下几种情况:

  • 情况一:消费者在消费完一条消息之后向 RabbitMQ 发送确认 Basic.Ack 命令,此时由于网络断开或者其他原因造成 RabbitMQ 并没有收到这个确认命令,那么 RabbitMQ 不会将此条消息标记删除。在重新建立连接之后,消费者还是会消费到这一条消息,这就造成了重复消费。
  • 情况二:生产者在使用 publisher confirm (发送方确认)机制的时候,发送完一条消息等待 RabbitMQ 返回确认通知,此时网络断开,生产者捕获到异常情况,为了确保消息可靠性选择重新发送,这样 RabbitMQ 中就有两条同样的消息,在消费的时候,消费者就会重复消费。

RabbitMQ也没有提供去重机制来保证“恰好一次”, 目前大多数主流的消息中间件都没有消息去重机制,也不保障“恰好一次”。

去重处理一般是在业务客户端实现,比如引入 GUID (Globally Unique Identifier) 的概念。针对 GUID,如果从客户端的角度去 重 ,那么需要引入集中式缓存,必然会增加依赖复杂度,另外缓存的大小也难以界定 。

建议在实际生产环境中,业务方根据自身的业务特性进行去重,比如业务消息本身具备幂等性,或者借助 Redis 等其他产品进行去重处理。

你可能感兴趣的:(rabbitmq,rabbitmq,消息传输保障)