图来自于《RocketMq技术内幕》
开局一张图,内容全靠问。(学而不思则罔,思而不学则殆)
首先问什么是NameServer?
一般中间件都是基于主题的订阅发布机制,生产者发送消息到消息服务器,消费者消费该消息服务器的消息,方式有两种,一种是消息服务器主动推送(push)给消费者,另一种是消费者主动(pull)获取消息。而nameServer就是消息服务器,从架构上可以看出,每一个组件都能做成集群模式,也是保证了高可用的特性。(架构设计无非就是追求三高,高可用高并发高性能),存在高可用就存在负载均衡,每一个Broker都会在部署的每一个NameServer上进行注册,然后根据负载均衡算法选择其中一个进行消息发送,然后与之建立长连接。nameServer每隔30秒就会检测该Broker是否存活(心跳机制),如果检测到Broker宕机了,就从注册表中移除。问:既然移除了一个Broker,那么生产者会马上知道吗?答:不会,为了保证消息发送的高可用。肯定赶紧安排另一台Broker或者是BrokerSlave(备胎)与之通信。
说了那么多,什么是Broker?
Broker是RocketMq的核心,负责消息的传递(提供者=》消费者)以及消息的持久化存储,消息的HA机制以及服务器过滤功能。
类似于我们买房时找的中介(代理)。
接着我们就要开始思考,NameServer是怎么启动的?它是怎么工作的?它做了什么?
1、NameServer启动流程
①创建NameServerConfig(业务参数)和NettyServerConfig(网络参数)对象,然后将配置信息填充到两个对象当中。
②加载KV配置,创建Netty网络对象,开启两个定时任务,a.NameServer每隔10秒扫描一次Broker,移除掉不激活状态下的Broker,b.NameServer每隔10秒打印一次KV配置
③注册JVM钩子函数并启动服务器,监听Broker以及生产者消息网络请求
2、NameServer的路由发现和路由剔除
①路由元信息(hashMap)
②路由注册和删除
也可以看这张图
一图胜千言,必考。
心跳包内部逻辑
总结:
其实看源码最重要的是要引发自己的思考,说实话,看完源码以后我是一脸懵逼的,感觉有一种他说什么就是什么,自己只要认同的感觉,而不是说,我能从代码中学到,他们是如何解决问题的,为什么要这样设计,这样设计的好处是什么。
首先是NameServer启动流程,就是加载配置信息做初始化,唯一亮点就是使用jvm钩子函数优雅地停止线程池。
其次我们了解到路由的注册,发现和删除,是通过发送心跳包的方式。Broker每隔30秒发送一个心跳包证明自己活着,每隔10秒扫描一下brokerLiveTable的lastUpdateTimestamp,检查时间是否更新,如果超过120秒没有更新就移除该broker。
当然这是简单的说法,详细的说法可以直接阅读源码,看看具体怎么实现的
RouteInfoManager#registerBroker路由的注册
public RegisterBrokerResult registerBroker(
final String clusterName,
final String brokerAddr,
f