设置

RabbitMQ消息服务用户手册.docx

集群恢复和故障转移

  • 前提,节点 a b 组成镜像队列
  1. a 先停,b后停
    • 该场景下B是Master,只要先启动B,再启动A即可。或者先启动A,再30秒之内启动B即可恢复镜像队列
  2. a、b 同时停
    • 该场景可能是由于机房掉电等原因造成的,只需在30秒之内连续启动A和B即可恢复镜像
  3. a先停,b后停,且 a 无法恢复
    • 因为 B 是 Master,所以等B起来以后,在B节点上调用控制台命令:rabbitmqctl forget_cluster node A 解除与 A 的 Cluster 关系,再将新的 Slave 节点加入B即可重新恢复镜像队列
  4. a先停,b后停,b无法恢复
    • 因为Master节点无法恢复,早在3.1.x时代之前没有什么好的解决方案,但是现在已经有解决方案了,在3.4.2以后的版本。因为B是主节点,所以直接启动A是不行的,当A无法启动的时候,也就没办法在A节点上调用之前的 rabbitmqctl forget_cluster_node B 命令了。新版本中,forget cluster node 支持 --offline 参数
    • 这就意味着允许 rabbitmqctl 在理想节点上执行该命令,迫使 RabbitMQ 在未启动 Slave 节点中选择一个节点作为 Master。当在A节点执行 rabbitmqctl forget cluster_node-offline B 时,RabbitMQ会 mock一个节点代表A,执行 forget cluster node 命令将 B 剔除 cluster,然后A就可以正常启动了,最后将新的 Slave 节点加入A即可重新恢复镜像队列
  5. A 先停、B 后停,且 A、B 均无法恢复,但是能得到 A 或 B 的磁盘文件
    • 这种场景更加难处理,只能通过恢复数据的方式去尝试恢复,将A或B的数据库文件默认在$RABBIT_HOME/var/lib/目录中,把它拷贝到新节点的对应 mulxia ,再将新节点的 hostname 改成A或B的hostname,如果是A节点(Slave)的磁盘文件,则按照场景4处理即可,如果是B节点(Master)的磁盘文件,则按照场景3处理,最后将新的Slave加入到新节点后完成恢复
  6. A先停、B后停,且A、B均无法恢复,且得不到A或B的磁盘文件
    • 凉凉

架构

image.png

迅速消息发送

  • 迅速消息是指消息不进行落库存储,不做可靠性的保障
  • 在一些非核心消息、日志数据、或者统计分析等场景下比较合适
  • 迅速消息的优点就是性能最高,吞吐量最大

确认消息发送

image.png

延迟消息发送

  • 延迟消息相对简单,就是我们在Message封装的时候添加delayTime属性即可
  • 需要插件
  • 场景
    • 在电商平台买到的商品签收后,不点击确认支付,那么系统自动会在7天(一定时间)去进行支付操作。
    • 自动超时作废的场景,你的优惠券/红包有使用时间限制,也可以用延迟消息机制。

批量消息发送

  • 批量消息是指我们把消息放到一个集合里统一进行提交,这种方案设计思路是期望消息在一个会话里,比如投掷到threadlocal里的集合,然后拥有相同会话ID,并且带有这次提交消息的SIZE等相关属性,最重要的一点是要把这批消息进行合并。
  • 对于Channel而言,就是发送一次消息。这种方式也是希望消费端在消费的时候,可以进行批量化的消费,针对于某一个原子业务的操作去处理,但是不保障可靠性,需要进行补偿机制。

image.png

顺序消息发送

  • 顺序消息,比较类似于批量消息的实现机制,但是也有些不同。
  • 要保障以下几点:
  1. 发送的顺序消息,必须保障消息投递到同一个队列,且这个消费者只能有一个(独占模式)
  2. 然后需要统一提交(可能是合并成一个大消息,也可能是拆分为多个消息),并且所有消息的会话ID一致
  3. 添加消息属性:顺序标记的序号、和本次顺序消息的SIZE属性,进行落库操作
  4. 并行进行发送给自身的延迟消息(注意带上关键属性:会话ID、SIZE)进行后续处理消费
  5. 当收到延迟消息后,根据会话ID、SIZE抽取数据库数据进行处理即可
  6. 定时轮训补偿机制,对于异常情况
    • 比如生产端消息没有完全投递成功、或者消费端落库异常导致消费端落库后缺少消息条目的情况

image.png

事务消息发送

  • 可以用以下解决方案取代 rabbitmq 自身事务消息
    • 采用类似可靠性投递的机制,也就是补偿机制。
  • 要求的数据源必须是同一个,也就是业务操作DB1数据库和消息记录DB2数据库使用同一个数据源
  • 然后利用重写 Spring DataSource TransactionManager,在本地事务提交的时候进行发送消息,但是也有可能事务提交成功但是消息发送失败,这个时候就需要进行补偿了。

image.png

幂等

  • 可能导致消息出现非幂等的原因:
  1. 可靠性消息投递机制
  2. MQ Broker服务与消费端传输消息的过程中的网络抖动

    1. 消费端故障或异常

image.png