zoukankan      html  css  js  c++  java
  • RabbitMQ 如何保证消息不丢失?

    RabbitMQ一般情况很少丢失,但是不能排除意外,为了保证我们自己系统高可用,我们必须作出更好完善措施,保证系统的稳定性。

    下面来介绍下,如何保证消息的绝对不丢失的问题,下面分享的绝对干货,都是在知名互联网产品的产线中使用。

    1.消息持久化

    2.ACK确认机制

    3.设置集群镜像模式

    4.消息补偿机制

    第一种:消息持久化

    RabbitMQ 的消息默认存放在内存上面,如果不特别声明设置,消息不会持久化保存到硬盘上面的,如果节点重启或者意外crash掉,消息就会丢失。

    所以就要对消息进行持久化处理。如何持久化,下面具体说明下:

    要想做到消息持久化,必须满足以下三个条件,缺一不可。

    1) Exchange 设置持久化

    2)Queue 设置持久化

    3)Message持久化发送:发送消息设置发送模式deliveryMode=2,代表持久化消息

    第二种:ACK确认机制

    多个消费者同时收取消息,比如消息接收到一半的时候,一个消费者死掉了(逻辑复杂时间太长,超时了或者消费被停机或者网络断开链接),如何保证消息不丢?

    这个使用就要使用Message acknowledgment 机制,就是消费端消费完成要通知服务端,服务端才把消息从内存删除。

    这样就解决了,及时一个消费者出了问题,没有同步消息给服务端,还有其他的消费端去消费,保证了消息不丢的case。

    第三种:设置集群镜像模式

    我们先来介绍下RabbitMQ三种部署模式:

    1)单节点模式:最简单的情况,非集群模式,节点挂了,消息就不能用了。业务可能瘫痪,只能等待。
    2)普通模式:默认的集群模式,某个节点挂了,该节点上的消息不能用,有影响的业务瘫痪,只能等待节点恢复重启可用(必须持久化消息情况下)。
    3)镜像模式:把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQ的HA方案

    为什么设置镜像模式集群,因为队列的内容仅仅存在某一个节点上面,不会存在所有节点上面,所有节点仅仅存放消息结构和元数据。下面自己画了一张图介绍普通集群丢失消息情况:

    如果想解决上面途中问题,保证消息不丢失,需要采用HA 镜像模式队列。

    下面介绍下三种HA策略模式:

    1)同步至所有的
    2)同步最多N个机器
    3)只同步至符合指定名称的nodes

    命令处理HA策略模版:rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]

    1)为每个以“rock.wechat”开头的队列设置所有节点的镜像,并且设置为自动同步模式
    rabbitmqctl set_policy ha-all "^rock.wechat" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
    rabbitmqctl set_policy -p rock ha-all "^rock.wechat" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

    2)为每个以“rock.wechat.”开头的队列设置两个节点的镜像,并且设置为自动同步模式
    rabbitmqctl set_policy -p rock ha-exacly "^rock.wechat"
    '{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}'

    3)为每个以“node.”开头的队列分配指定的节点做镜像
    rabbitmqctl set_policy ha-nodes "^nodes."
    '{"ha-mode":"nodes","ha-params":["rabbit@nodeA", "rabbit@nodeB"]}'

    但是:HA 镜像队列有一个很大的缺点就是:   系统的吞吐量会有所下降

     

    第四种:消息补偿机制

    为什么还要消息补偿机制呢?难道消息还会丢失,没错,系统是在一个复杂的环境,不要想的太简单了,虽然以上的三种方案,基本可以保证消息的高可用不丢失的问题,

    但是作为有追求的程序员来讲,要绝对保证我的系统的稳定性,有一种危机意识。

    比如:持久化的消息,保存到硬盘过程中,当前队列节点挂了,存储节点硬盘又坏了,消息丢了,怎么办?

    产线网络环境太复杂,所以不知数太多,消息补偿机制需要建立在消息要写入DB日志,发送日志,接受日志,两者的状态必须记录。

    然后根据DB日志记录check 消息发送消费是否成功,不成功,进行消息补偿措施,重新发送消息处理。

  • 相关阅读:
    IIS6为应用程序池**提供服务的进程与 World Wide Web Publishing 服务通信时遇到致命错误
    C# WINFORM 强制让窗体获得焦点
    数据库性能优化详解
    sqlserver 2008 修改表结构不能保存
    SQL性能优化
    aspnet打印 设置(页脚 一些数据显示在打印页的最下面)
    图片转成byte数组
    在配置文件中定义初始值然后读取
    DOM编程
    html动态显示时间
  • 原文地址:https://www.cnblogs.com/flyrock/p/8859203.html
Copyright © 2011-2022 走看看