NameServer作为RocketMQ的服务路由中心,其主要起到了如下的作用:
服务注册
Broker在启动的时候会向NameServer注册自己的信息,Broker宕机时NameServer也会剔除该Broker信息
路由发现
Produer发送消息或Consumer拉取消息,都需要从NameServer获取路由信息
通信、维持心跳
Producer、Consumer和Broker都会与NameServer进行通信或定时发送心跳
(NameServer集群互相独立,因此就可能会造成某时刻数据不一致,但不会产生太大的影响,最多是某时刻proder发送的消息不均衡)
1.1通信Broker会每隔30s向NameServer发送心跳(如果是NameServer集群,则会发送给每个NameServer),同时包含自己的相关信息,如名称、地址、topic等,NameServer会维护每个Broker的相关信息,并记录收到心跳时的时间戳,用于判断Broker是否宕机(默认s内没有收到Broker的心跳则会将其从列表中剔除);
Producer和Consumer会每30s从NameServer获取最新的topic信息更新到本地,Producer会用于负载均衡处理消息发送
NameServer和所有的Broker保持一个长连接,且每隔10s会扫描一次本地维护Broker信息的table,比较每个broker上次收到心跳的时间戳,如果已经超过s了,说明s内没收到该broker的心跳,则会将该broker的信息移除,更新topic的路由信息。
二、NameServer的启动启动类:org.apache.rocketmq.namesrv.NamesrvStartup
1publicstaticNamesrvControllermain0(String[]args){2try{3NamesrvControllercontroller=createNamesrvController(args);4start(controller);5returncontroller;6}catch(Throwablee){7e.printStackTrace();8System.exit(-1);9}returnnull;12}
整个流程很简单,分量大步:
创建NamesrvController
启动(NamesrvController)
NamesrvController是NameServer的核心组件,用于接收网络请求。
2.1创建NamesrvController解析配置首先要做的就是解析传入的配置参数等信息,将其保存到NamesrvConfig和NettyServerConfig两个类中。
NamesrvConfig
主要包含了NameServer自身运行的参数
NettyServerConfig
主要包含了Netty服务端的配置参数
首先看下两个类的默认配置:
根据debug的显示,在创建后就有的默认配置:
NamesrvConfigNamesrvConfig默认配置1//RocketMQ的主目录2privateStringrocketmqHome=System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY,System.getenv(MixAll.ROCKETMQ_HOME_ENV));3//NameServer存储KV配置属性的文件地址4privateStringkvConfigPath=System.getProperty("user.home")+File.separator+"namesrv"+File.separator+"kvConfig.json";5//默认配置文件的地址,指定配置文件启动通过-cconfigPath命令6privateStringconfigStorePath=System.getProperty("user.home")+File.separator+"namesrv"+File.separator+"namesrv.properties";7//生产环境名称8privateStringproductEnvName="center";9//是否启动集群测试10privatebooleanclusterTest=false;11//是否支持有序消息,默认不支持12privatebooleanorderMessageEnable=false;NettyServerConfig默认配置
1//端口号,下面启动时被默认覆盖为privateintlistenPort=;3//Netty工作线程数4privateintserverWorkerThreads=8;5//Netty的public线程池的线程数,默认是06privateintserverCallbackExecutorThreads=0;7//Netty的IO线程池线程数量。主要负责处理网络请求,解析请求包,再转发到各个业务线程池。最后返回结果8privateintserverSelectorThreads=3;9//Broker端的两个配置参数10//sendOneWay消息请求的最大并发度11privateintserverOnewaySemaphoreValue=;12//异步消息发送的最大并发数13privateintserverAsyncSemaphoreValue=64;14//网络连接最大空闲时间默认s,超过该空闲时间的连接被关闭15privateintserverChannelMaxIdleTimeSeconds=;16//网络Socket发送缓冲区大小默认64KB,下同17privateintserverSocketSndBufSize=NettySystemConfig.socketSndbufSize;18//接收端缓存区大小19privateintserverSocketRcvBufSize=NettySystemConfig.socketRcvbufSize;20//是否开启ByteBuffer缓存21privatebooleanserverPooledByteBufAllocatorEnable=true;/**24*makemakeinstall25*26*27*../glibc-2.10.1/configure\--prefix=/usr\--with-headers=/usr/include\28*--host=x86_64-linux-gnu\--build=x86_64-pc-linux-gnu\--without-gd29*/30//是否启用Epoll模型,Linux下默认是开启的31privatebooleanuseEpollNativeSelector=false;
serverCallbackExecutorThreads
puclic任务线程数。Netty根据RequestCode确定业务类型,内部每个业务类型对应一个线程池处理,如果没有对应的RequestCode,则由该public线程池处理
在2.2.1中创建NettyServer网络处理器时,如果为0,则会改为4个
1:-c处理
设置NameServer监听的端口,硬编码:
如果指定了-c,即指定配置文件启动,则进行加载,并设置到两个配置类中(具体怎么做的就不深究了)
1finalNamesrvConfignamesrvConfig=newNamesrvConfig();2finalNettyServerConfignettyServerConfig=newNettyServerConfig();3nettyServerConfig.setListenPort();4//解析三个配置对象5if(