1.namesrv的作用
namesrv,命名服务,顾名思义,应该是做服务管理之类的,类似于zookeeper,Nacos。
在RocketMQ中,实际进行消息存储、推送等核心功能的是Broker。那namesrv具体做什么用呢?namesrv的核心作用其实就只有两个。
- 维护Broker的服务地址并进行及时的更新。
- 给Producer和Consumer提供服务获取Broker列表。
2.源码解析
2.1.NamesrvStartup namesrv启动类
public static void main(String[] args) {
main0(args);
}
public static NamesrvController main0(String[] args) {
/NameServer启动的核心组件,NamesrvController
//类似于Web应用里的Controller,这个组件就是用来接收网络请求的。那NameServer到底要接收哪些网络请求?
try {
NamesrvController controller = createNamesrvController(args);
start(controller);
String tip = "The Name Server boot success. serializeType=" + RemotingCommand.getSerializeTypeConfigInThisServer();
log.info(tip);
System.out.printf("%s%n", tip);
return controller;
} catch (Throwable e) {
e.printStackTrace();
System.exit(-1);
}
return null;
}
createNamesrvController(…)主要是加载namesrv的主要配置信息,并创建NameSrvController类似web服务的contoller。
- NameSrvConfig 包含NameServer自身运行的参数
- NettyServerConfig 包含Netty服务端的配置参数,Netty服务端口默认指定了9876。端口可以修改
2.2.start(controller)
public static NamesrvController start(final NamesrvController controller) throws Exception {
//初始化,主要是初始化几个定时任务
boolean initResult = controller.initialize();
if (!initResult) {
controller.shutdown();
System.exit(-3);
}
//启动netty服务
controller.start();
return controller;
}
2.3.controller.initialize()
public boolean initialize() {
//加载KV配置
this.kvConfigManager.load();
//创建NettyServer网络处理对象
this.remotingServer = new NettyRemotingServer(this.nettyServerConfig, this.brokerHousekeepingService);
//Netty服务器的工作线程池
this.remotingExecutor =
Executors.newFixedThreadPool(nettyServerConfig.getServerWorkerThreads(), new ThreadFactoryImpl("RemotingExecutorThread_"));
//注册Processor,把remotingExecutor注入到remotingServer中
this.registerProcessor();
//开启定时任务:每隔10s扫描一次Broker,移除不活跃的Broker
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
NamesrvController.this.routeInfoManager.scanNotActiveBroker();
}
}, 5, 10, TimeUnit.SECONDS);
//开启定时任务:每隔10min打印一次KV配置
this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
NamesrvController.this.kvConfigManager.printAllPeriodically();
}
}, 1, 10, TimeUnit.MINUTES);
return true;
}
这里我们可以看到一个非常熟悉的功能NamesrvController.this.routeInfoManager.scanNotActiveBroker();每隔10s扫描一次Broker,移除不活跃的Broker。
// 扫描不活动的Broker
public void scanNotActiveBroker() {
//扫描的就是这个BrokerLiveTable,路由信息表。还有一个Brokernames
Iterator<Entry<String, BrokerLiveInfo>> it = this.brokerLiveTable.entrySet().iterator();
while (it.hasNext()) {
Entry<String, BrokerLiveInfo> next = it.next();
long last = next.getValue().getLastUpdateTimestamp();
//根据心跳时间判断是否存活的核心逻辑。两分钟未发送心跳注册请求
if ((last + BROKER_CHANNEL_EXPIRED_TIME) < System.currentTimeMillis()) {
RemotingUtil.closeChannel(next.getValue().getChannel());
it.remove();
log.warn("The broker channel expired, {} {}ms", next.getKey(), BROKER_CHANNEL_EXPIRED_TIME);
this.onChannelDestroy(next.getKey(), next.getValue().getChannel());
}
}
}
2.4.路由元信息维护
2.3这里有几个关键的信息,namesrv主要通过5个属性来维护路由元信息。
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;
2.4.1 topicQueueTable
说明:Topic消息队列路由信息,消息发送时根据路由表进行负载均衡。
数据结构:HashMap结构,key是Topic名字,value是一个类型是QueueData的队列集合。在第一章就讲过,一个Topic中有多个队列。QueueData的数据结构如下:
topicQueueTable:{
"TestTopic": [
{
"brokerName": "broker-a",
"readQueueNums":4,
"writeQueueNums":4,
"perm":6,
"topicSynFlag":0,
},
{
"brokerName": "broker-b",
"readQueueNums":4,
"writeQueueNums":4,
"perm":6,
"topicSynFlag":0,
}
]
}
2.4.2 BrokerAddrTable
说明:Broker基础信息,包含BrokerName、所属集群名称、主备Broker地址。
数据结构:HashMap结构,key是BrokerName,value是一个类型是BrokerData的对象。BrokerData的数据结构如下(可以结合下面Broker主从结构逻辑图来理解):
brokerAddrTable:{
"broker-a": {
"cluster": "DefaultCluster",
"brokerName": "broker-a",
"brokerAddrs": {
//brokerId:broker address
0: "192.168.43.199:10911",
1: "192.168.43.199:11011"
}
},
"broker-b": {
"cluster": "DefaultCluster",
"brokerName": "broker-b",
"brokerAddrs": {
0: "192.168.43.199:11911",
1: "192.168.43.199:12911"
}
}
}
2.4.3 ClusterAddrTable
说明:Broker集群信息,存储集群中所有Broker名称。
数据结构:HashMap结构,key是ClusterName,value是存储BrokerName的Set结构。
数据结构:
clusterAddrTable:{
"DefaultCluster": ["broker-a","broker-b"]
}
2.4.4 BrokerLiveTable
说明:Broker状态信息。NameServer每次收到心跳包时会替换该信息
数据结构:HashMap结构,key是Broker的地址,value是BrokerLiveInfo结构的该Broker信息对象。BrokerLiveInfo的数据结构如下:
brokerLiveTable:{
"192.168.43.199:10911": {
"lastUpdateTimestamp": 1518270318980,
"dataVersion":versionObj,
"channel":channelObj,
"haServerAddr":"" //master地址,初次请求为空,slave向master注册后返回
},
"192.168.43.199:11011": {
"lastUpdateTimestamp": 1518270318980,
"dataVersion":versionObj,
"channel":channelObj,
"haServerAddr":"192.168.43.199:10911"
},
"192.168.43.199:11911": {
"lastUpdateTimestamp": 1518270318980,
"dataVersion":versionObj,
"channel":channelObj,
"haServerAddr":""
},
"192.168.43.199:12911": {
"lastUpdateTimestamp": 1518270318980,
"dataVersion":versionObj,
"channel":channelObj,
"haServerAddr":"192.168.43.199:11911"
}
}
2.4.5 filterServerTable
说明:Broker上的FilterServer列表,消息过滤服务器列表,consumer拉取数据是通过filterServer拉取,consumer向Broker注册。
数据结构:HashMap结构,key是Broker地址,value是记录了filterServer地址的List集合。
4768

被折叠的 条评论
为什么被折叠?



