注:本文为RocketMQ系列文章第二讲。
路由中心简介
rocketmq路由中心由nameserver集群构成。nameserver是一个轻量级的路由中心, 维护着broker注册信息。值的说明的是nameserver是一个无状态结点, nameserver集群中的每个结点都保存所有broker的全量注册信息 。路由中心作为rocketmq客户端与服务端交互的纽带, 客户端不直接从broker查找topic, 而是通过路由中心来获topic的路由信息, 然后与相关broker进行通信。
路由元信息
rocketmq路由元信息维护在org.apache.rocketmq.namesrv.routeinfo.RouteInfoManager中, 主要属性如下:
private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
1.topicQueueTable: Topic消息队列的路由信息,维护了topic与queue的对应关系
QueueData |
---|
private String brokerName; //broker名字 |
private int readQueueNums; //读队列数 |
private int writeQueueNums; //写队列数 |
private int perm; //队列权限 6: 读写, 4: 禁写, 2: 禁读 |
2.brokerAddrTable: 维护Broker基础信息,包括Broker所属集群, Broker名称, 主从Broker地址
BrokerData |
---|
private String cluster; //集群名称 |
private String brokerName; //broker名称 |
private HashMap<Long /**brokerId */ , String /**broker address */ > brokerAddrs; // broker地址 |
3.clusterAddrTable: 维护集群与Broker关系
4.brokerLiveTable: 维护broker心跳信息, 每一次心跳都会更新时间
BrokerLiveInfo |
---|
private long lastUpdateTimestamp; // 上次更新时间 |
private DataVersion dataVersion; // 版本 |
private Channel channel; // 通道 |
private String haServerAddr; // 高可用服务器地址 |
5.filterServerTable: Broker上的FilterServer列表, 用于类模式消息过滤
路由注册
路由注册是通过Broker与NameServer的心跳信息实现的。
-
路由上报 (Broker端实现,状态码RequestCode.REGISTER_BROKER)
Broker启动时开启一个定时任务,每隔30秒(可通过配置broker参数registerNameServerPeriod设置)向集群中所有NameServer发送心跳包。心跳包主要信息包括集群名称、broker地址、broker名称、brokerId、主题队列信息、类过滤信息等。 -
路由维护(NameServer实现)
核心实现在org.apache.rocketmq.namesrv.routeinfo.RouteInfoManager#registerBroker, 主要维护RouteInfoManager类中的topicQueueTable、brokerAddrTable、clusterAddrTable、brokerLiveTable和filterServerTable路由注册元信息。
故障剔除
-
核心实现
路由剔除实现类为org.apache.rocketmq.namesrv.routeinfo.RouteInfoManager#onChannelDestroy -
剔除过程
在NameServer初始化org.apache.rocketmq.namesrv.NamesrvController#initialize过程中会开启一个定时任务, 每隔10s扫描brokerLiveTable状态表, 如果BrokerLive的lastUpdateTimestamp的时间戳距当前时间超过120s, 则认为Broker失效, 移除失效的Broker, 关闭与Broker连接, 并同时更新topicQueueTable、brokerAddrTable、brokerLiveTable与filterServerTable。 -
路由删除触发条件
RocketMQ有两个触发点来触发路由删除, 两者执行逻辑都是一样的:
(1) NameServer定时扫描brokerLiveTable检测上次心跳包与当前系统时间的时间差, 如果时间差大于120s, 则需要移除该Broker信息。
(2)Broker在正常被关闭的情况下,会执行unregisterBroker指令, 移除nameserver上的路由信息。
路由发现
broker中topic路由信息注册到nameserver上后, nameserver不主动推送路由信息给每个客户端, 而是由客户端定时地去拉取主题路由信息, 对应状态码为RequestCode.GET_ROUTEINTO_BY_TOPIC。核心实现在
org.apache.rocketmq.namesrv.processor.DefaultRequestProcessor#getRouteInfoByTopic。
总结
RockeMQ路由中心内容到这里已经结束了, 如果读者有任何问题或想要了解的细节, 可以在文章后留言, 笔者会尽所能, 对问题进行认真解答。
注: 因笔者技术水平有限, 文章中描述不准确的地方, 还请多多批评指正。