RocketMQ的NameServer执行流程学习梳理
首先看流程图
从流程图中,我们可以梳理如下信息:
首先NamesrvStartUp启动,首先经过main()方法,也是我们常见的main方法进入到main0()执行创建controller操作与启动controller操作这两个操作。而创建controller的操作则首先需要拿到namesrvConfig的配置信息和NettyServerConfig的配置信息,此时会 创建这两个对象,并填充配置信息然后放入到创建的controller对象中的构造函数中,并进行controller的启动操作,而启动操作首先会初始化一些信息和添加jvm钩子,也即会进行如下操作:加载键值对配置管理器、创建远程服务器remotingServer,创建远程线程池remotingExecutor、注册处理器、创建两个定时任务执行心跳检查、注册jvm钩子,启动Controller。
那么问题来了,为什么要使用nameServer作为注册中心,而没有使用zookeeper呢?
与nameServer相比,zookeeper:1.复杂性:zookeeper基于CAP理论实现,其宕机之后,会进行选举,而选举的过程本身就是一个耗时的过程2.可用性:zookeeper实现是基于CP的,因此zookeeper是强调强一致性的,其牺牲了可用性具体体现:同时nameServer复杂性降低在于其代码量少,同时nameServer节点之间互不通信,因此无法进行数据复制。但可通过部署多台broker来实现高可用。因为broker的高可用方案在于如果broker服务器没有宕机时,进行轮询队列,发送消息;而当brokerA服务器宕机时,则会采用的策略是:例如在接下来的5分钟内会跳过BrokerA,而选择其他的broker中的队列,进行消息发送。此时没有涉及到选举过程,不需要在这里耗时选举。
路由注册信息:zookeeper,数据只要写到主节点,就会进行数据复杂到从节点。而NameServer的各个节点是互不通信的,因此无法进行数据复制。在broker节点启动时,轮询nameServer列表,与每个nameServer建立长连接,发起注册请求。NameServer内部会维护Broker列表,用来动态存储Broker信息。Broker和NameServer之间会进行心跳检测,broker每隔30s会将最新的心跳包信息发生给NameServer。心跳包中包含了Broker的相关信息,NameServer接收到之后,会更新时间戳,记录Broker的最新存活时间,如果broker发生的的最新时间戳与当前时间相比超过120s则进行路由剔除操作。
NameServer Topic路由注册中读写锁:对broker表允许并发读,串行写,此时可以使用读写锁。