源码解析-RocketMQ-namesrv

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集合。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值