可靠性优先的场景

顺序消息

默认情况下,消息是无序的。一些需要消息是顺序的场景,比如:订单的生成,付款,发货。分为全局顺序和局部顺序。

全局顺序

某个topic下整体都是有顺序的。要保证全局顺序消息,需要先把 Topic 的读写队列数设置为一,然后 Producer 和 Consumer 的并发设置也要是一 。

局部顺序

只保证某一组消息具有顺序即可。要保证部分消息有序,需要发送端和消费端配合处理 。 在发送端,要做到 把同一业务 ID 的消息发送到同一个 Message Queue ;在消费过程中,要做到从 同一个 Message Queue 读取的消息不被并发处理,这样才能达到部分有序 。

  1. 发送端使用 MessageQueueSelector类来控制 把消息发往哪个 Message Queue。

  2. 消费端通过使用 MessageListenerOrderly类 来解决单 Message Queue 的消 息被并发处理的问题。原理是:MessageListenerOrderly为每个Message Queue增加一把锁。

消息重复问题

在分布式系统中,消息的一定成功和消息重复问题中,rocketmq选择了保证消息一定成功。因此,需要消费方来处理消息重复问题。通常有2种方法:

  1. 通过幂等。

  2. 维护消息已经消费记录。

动态增减机器

动态增减 NameServer

  1. 因为是属于broker上报信息,因此可以直接更换nameServer地址。

  2. 通过rocketmq.namesrv.domain.subgroup设置,提供一个url接口,返回nameServer地址。

动态增减 Broker

增加:

由于业务增长,需要对集群进行扩容的时候,可以动态增加 Broker角色的 机器 。 只增加 Broker 不会对原有的 Topic 产生影响,原来创建好的 Topic 中数 据的读写依然在原来的那些 Broker上进行。

集群扩容后, 一 是可以 把新 建的 Topic 指定到新的 Broker 机器上,均衡利 用资源;另一种方式是通过 updateTopic命令更改现有的 Topic 配置,在新加 的 Broker 上创建新的队列 。

减少:

减少 Broker要看是否有持续运行的 Producer,当一个 Topic 只有一个 Master Broker,停掉这个 Broker后,消息的发送肯定会受到影响,需要在停止这个 Broker 前,停止发送消息 。如果有多个Master Broker,如果使用同步发送消息,则会自动向另外的Master Broker发送消息。如果是异步发送,则会丢失切换过程中的消息。

各种故障对消息的影响

  1. Broker正常关闭,启动;

  2. Broker异常 Crash,然后启动;

  3. OS Crash,重启;

  4. 机器断电,但能马上恢复供电;

  5. 磁盘损坏;

  6. CPU、 主板、内存等关键设备损坏 。

第 1 种情况 属于可控的软件 问题,内存中的 数据不会丢失 。 如果重启过 程中有持续运行的 Consumer, Master机器出故障后, Consumer会自动 重连 到对应的 Slave 机器,不会有消息丢失和偏差 。 当 Master 角色的机器 重启 以 后, Consumer又会重新连接到 Master机器(注意在启动 Master机器的时候, 如果 Consumer 正在从 Slave 消费消息,不要停止 Consumer。 假如 此时先 停止 Consumer后再启动 Master机器,然后再启动 Consumer,这个时候 Consumer 就会去读 Master机器上已经滞后的 offset值,造成消息大量重复)。

如果第 1 种情况出现时有持续运行的 Producer, 一 台 Master 出故障后, Producer只能向 Topic下其他的 Master机器发送消息,如果 Producer采用同步 发送方式,不会有消息丢失 。

第 2、 3、 4种情况属于软件故障,内存的数据可能丢失,所 以刷盘策略不 同,造成的影响也不同,如果 Master、 Slave都配置成 SYNC_FLUSH,可以达 到和第 1种情况相同的效果 。

第 5' 6 种情况 属于硬件故障 ,发生第 5' 6 种 情况的故障,原有 机器的 磁 盘数据可能会丢失。 如果Master和Slave机器间配置成同步复制方式,某一台机器 发生 5 或 6 的故 障,也可以达 到消息不 丢失的效果 。如果 Master 和 Slave机器间是异步复制,两次 Sync间的消息会丢失。

总的来说,当设置成:

  1. 多 Master,每个 Master 带有 Slave;

  2. 主从之间设置成 SYNC_MASTER;

  3. Producer 用同 步方式写;

  4. 刷盘策略设置成 SYNC FLUSH。

就可以消除单点依赖,即使某台机器出现极端故障也不会丢消息 。

消息优先级

不支持。

Last updated

Was this helpful?