NameServer 与zk
1.nameServer 之间互不通信,故不存在强一致性,即不同的producer看到的视图可能时不一样的,(如何保证最终一致的?)
2.nameServer维护的boker信息 发生变化时,不会像zk某个节点被监听那样,给订阅放发送服务下线事件,所以订阅方无法及时发现服务下线(如何发现的?)
路由元信息

1.topicQueueTable:topic消息队列路由信息,消息发送时根据路由表进行负载均衡
2.brokerAddrTable:Broker基础信息,包含brokerName,所属集群名称,主备broker地址
3.clusterAddrTable:Broker集群信息,存储集群中所有broker名称
4.brokerLiveTable:Broker状态信息。nameserver每次收到心跳包时会替换该信息
5.filterServerTable:Broker上的FilterServer列表,用于类模式消息过滤。
一个Topic拥有多个消息队列,一个Broker为每一主题默认创建4个都队列和4个写队列,多个Broker组成一个集群,BrokerName由相同的多台Broker组成Master-Slave架构(对比kafaka:分区),brokerId为0代表Master,大于0表示Slave。
路由注册
RocketMQ路由注册是通过Broker与NameServer的心跳功能实现的。Broker启动时向集群中所有的Name Server发送心跳语句,每隔30s向集群中所有NameServer发送心跳包,NameServer收到Broker心跳包时会更新broker,LiveTable缓存中BrokerLiveInfo的lastUpdateTimestamp,然后NameSer每隔10s扫描broker Live Tale,如果连续120s没有收到心跳包,NameServer将移除该Broker的路由信息同时关闭Socket连接
注册源码:

public List<RegisterBrokerResult> registerBrokerAll( final String clusterName, final String brokerAddr, final String brokerName, final long brokerId, final String haServerAddr, final TopicConfigSerializeWrapper topicConfigWrapper, final List<String> filterServerList, final boolean oneway, final int timeoutMills, final boolean compressed) { final List<RegisterBrokerResult> registerBrokerResultList = Lists.newArrayList(); List<String> nameServerAddressList = this.remotingClient.getNameServerAddressList(); if (nameServerAddressList != null && nameServerAddressList.size() > 0) { final RegisterBrokerRequestHeader requestHeader = new RegisterBrokerRequestHeader(); requestHeader.setBrokerAddr(brokerAddr); requestHeader.setBrokerId(brokerId); requestHeader.setBrokerName(brokerName); requestHeader.setClusterName(clusterName); requestHeader.setHaServerAddr(haServerAddr); requestHeader.setCompressed(compressed); RegisterBrokerBody requestBody = new RegisterBrokerBody(); requestBody.setTopicConfigSerializeWrapper(topicConfigWrapper); requestBody.setFilterServerList(filterServerList); final byte[] body = requestBody.encode(compressed); final int bodyCrc32 = UtilAll.crc32(body); requestHeader.setBodyCrc32(bodyCrc32); final CountDownLatch countDownLatch = new CountDownLatch(nameServerAddressList.size()); for (final String namesrvAddr : nameServerAddressList) { brokerOuterExecutor.execute(new Runnable() { @Override public void run() { try { RegisterBrokerResult result = registerBroker(namesrvAddr,oneway, timeoutMills,requestHeader,body); if (result != null) { registerBrokerResultList.add(result); } log.info("register broker[{}]to name server {} OK", brokerId, namesrvAddr); } catch (Exception e) { log.warn("registerBroker Exception, {}", namesrvAddr, e); } finally { countDownLatch.countDown(); } } }); } try { countDownLatch.await(timeoutMills, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { } } return registerBrokerResultList; }
每一个请求RocketMQ都会定义一个RequestCode,然后在服务端会对应相应的网络处理器,只需整库搜索RequestCode即可找到相应的处理逻辑。
registerBroker:

读写者锁




浙公网安备 33010602011771号