RocketMQ NameServer如何保证数据最终一致

NameServer是RocketMQ的命名服务(路由中心、注册中心),提供更新和发现Broker服务的功能,是几乎无状态节点,可集群部署。NameServer节点之间互不通信,路由变化也不会马上通知客户端(生产者和消费者)。

既然NameServer的节点之间互不通信,变更也不发送通知,那又是如何保证数据最终一致的呢?

下面分别从路由更新和路由发现进行介绍:

路由更新

  1. Broker节点在启动时,轮询NameServer集群,与每个NameServer节点建立长连接,发起注册请求。
  2. Broker节点注册成功后,每隔30s定期向NameServer上报Topic路由信息,NameServer收到心跳包后记录Broker的最新时间戳。
  3. Broker节点正常下线时,会与NameServer断开长连接,Netty的通道关闭,监听器会监听到连接断开事件,然后将这个Broker剔除掉。
  4. NameServer中有一个定时任务,每隔10s扫描Broker列表,如果Broker的最新时间戳距离当前时间超过120s,会判定Broker失效并将其剔除掉。

路由发现

生产者

生产者与NameServer集群中的一个随机节点建立长连接,每隔30s从NameServer读取Topic路由信息,并向提供Topic服务的Master Broker建立长连接,且定时向Master Broker发送心跳。

消费者

消费者与NameServer集群中的一个随机节点建立长连接,每隔30s从NameServer拉取Topic路由信息,并向提供Topic服务的Master/Slave Broker建立长连接,且定时向Master/Slave Broker发送心跳。消费者可以从Master/Slave Broker订阅消息,订阅规则由Broker配置决定。


无论是生产者还是消费者,都是每隔30s从NameServer拉取Topic路由信息,如果生产者和消费者在这30s内,向某个宕机的broker发送或消费消息呢?

RocketMQ通过重试机制和Broker规避来保证消息可靠性:

重试机制

消息发送重试

生产者连接Broker发起消息发送请求时,可能会因为网络故障、服务异常等原因导致调用失败。为保证消息的可靠性,生产者会按照设置的重试次数一直重试发送消息。
同步发送和异步发送模式均支持消息发送重试。

消息消费重试

消费者出现异常,消费某条消息失败时,会根据消费重试策略重新投递该消息进行故障恢复。超过一次定数后若还未消费成功,则该消息将不再继续重试,直接被发送到死信队列中。

Broker规避

在一次消息发送过程中规避上次发送失败的Broker,在一时间段内,生产者不会选择该Broker上的消息队列,提高发送消息的成功率。

你可能感兴趣的:(中间件,java,rocketmq,java-rocketmq,NameServer)