Ezreal 书架 Ezreal 书架
Home
  • 《Go程序员面试笔试宝典》
  • 《RabbitMQ 实战指南》
  • 《深入理解kafka》
  • MySQL45讲
  • 透视HTTP协议
  • 结构化数据的分布式存储系统
  • Raft 共识算法
Home
  • 《Go程序员面试笔试宝典》
  • 《RabbitMQ 实战指南》
  • 《深入理解kafka》
  • MySQL45讲
  • 透视HTTP协议
  • 结构化数据的分布式存储系统
  • Raft 共识算法
  • RabbitMQ简介

  • RabbitMQ 入门

  • 客户端开发向导

  • RabbitMQ 进阶

    • 消息何去何从
    • 过期时间 (TTL)
    • 死信队列
    • 延迟队列
    • 优先级队列
    • RPC 实现
    • 持久化
    • 生产者确认
    • 消费端要点介绍
    • 消息传输保障
    • 小结
  • RabbitMQ 管理

  • RabbitMQ实战指南
  • RabbitMQ 进阶
ezreal_rao
2023-04-18

消息传输保障

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

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

RabbitMQ 支持其中的 "最多一次" 和 "最少一次"。其中 "最少一次" 投递实现需要考虑以下这个几个方面的内容:

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

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

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

那么 RabbitMQ 有没有去重的机制来保证 "恰好一次" 呢?答案是并没有,不仅是 RabbitMQ , 目前大多数主流的消息中间件都没有消息去重机制,也不保障 "恰好一次"。去重处理一般是在业务客户端实现,比如引入 GUID (Globally Unique Identifier) 的概念。针对 GUID ,如果从客户端的角度去重 ,那么需要引入集中式缓存,必然会增加依赖复杂度,另外缓存的大小也难以界定 。 建议在实际生产环境中,业务方根据自身的业务特性进行去重,比如业务消息本身具备 ' 幂等 ' 性,或者借助 Redis 等其他产品进行去重处理。

#mq#rabbitmq#amq
上次更新: 5/9/2023, 10:58:32 AM
消费端要点介绍
小结

← 消费端要点介绍 小结→

最近更新
01
为什么我的MySQL会抖一下
07-15
02
HTTP 性能优化面面观
07-12
03
WebSocket:沙盒里的 TCP
07-12
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Ezreal Rao | CC BY-NC-SA 4.0
豫ICP备2023001810号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式