问题背景

  1. 越来越多的关键业务开始使用RabbitMQ,比如支付,外卖订单,所以深入理解RabbitMQ如何保证消息的可靠性非常重要。
  2. 本文可靠性主要指消息接收后不丢,并且保证至少投递一次。
  3. 消息不丢对MQ来说消息的非常关键,但是没有一种机制能保证绝对可靠,所以深入理解RabbitMQ的保证可靠性的手段,然后尽量避免踩到可能丢消息的坑。

不同场景下的可靠性

可靠性保证级别 可靠级别 保证手段 行为 丢失消息的场景 缺点
场景一 开启持久化开启镜像队列开启confirm 消息同步写到双节点的磁盘才返回成功 两个节点同时宕机,重启后所有消息都可以恢复一个节点宕机,不会造成丢消息 confirm是采用pipeline异步回复的,存在状态不一致风险,如果客户端同步等待confirm,性能会非常低。无法和数据库事务结合
场景二 开启持久化开启镜像队列 开启事务 消息同步写到双节点的内存队列,后台线程异步刷磁盘 两个节点同时宕机,没来得及持久化的消息会丢失; 一个节点宕机,不会造成丢消息 主要是性能损耗比较大,QPS只有confirm的一半左右,通过抓包分析也能验证这个结果。 当前的默认行为
场景三 关闭持久化开启镜像队列 消息只同时写到两个节点的内存,不刷磁盘 两个节点同时宕机,所有消息都会丢失一个节点宕机,不会造成消息宕机 高性能,高可用,但是两个节点同时宕机会丢消息
场景四 关闭持久化关闭镜像队列 消息只同时写到一个节点的内存,不刷磁盘 两个节点同时宕机,所有消息都会丢失一个节点宕机,消息丢失,但是服务依然可用,queue可以切换到另外的机器 纯粹为高性能,可靠性低,任何一个节点宕机,都会导致消息丢失

参考资料

https://www.rabbitmq.com/ha.html

https://www.rabbitmq.com/confirms.html

https://www.rabbitmq.com/tutorials/tutorial-two-python.html

http://www.rabbitmq.com/blog/2011/02/10/introducing-publisher-confirms/

results matching ""

    No results matching ""