第一章 NameServer
来源:互联网 发布:剑三mmd花萝捏脸数据 编辑:程序博客网 时间:2024/06/09 20:58
一、NameServer
NameServer包下面总共就三个模块
1、kvconfig模块
处理key,value类型的配置,目前只使用了了ORDER_TOPIC_CONFIG key
2、processor模块
处理来自consumer,producer,broker的请求
3、routeinfo模块
处理broker集群信息,broker与topic, topic的队列信息
二、功能整合
1、NamesrvController
整合三个模块的功能,通过NettyServer客户端提供服务
2、NamesrvStartup
加载NettyServerConfig与NameSrvConfig,其中采用apache cli框架读取命令行参数的方式来加载配置,这种配置文件加载方式能够有效隔离不同环境配置。启动服务。
三 按模块分析
1.kvconfig
KVConfigManager
kv属性管理
KVConfigSerializeWrapper
kv属性序列化增强
2.processor模块
DefaultRequestProcessor
默认请求处理,处理来自C,P,B 的请求,维护与broker的心跳处理的请求类型:
ClusterTestRequestProcessor
集群模式请求处理 继承与上面的,在取不到topic的时候去admin取,这是唯一的区别
3.routeinfo模块
BrokerHousekeepingService
broker链接保持服务
RouteInfoManager
路由信息管理,通过读写锁控制信息。主要来分析一下其中的方法
RouteInfoManager字段
private final ReadWriteLock lock = new ReentrantReadWriteLock(); 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;
1.lock,用来保护的读写锁 2.topicQueueTable,根据topic存储topic对应的queue的关系 3.brokerAddrTable根据brokerName存储broker的addr和cluster信息 4.brokerLiveTable存放broker的存活信息 5.filterServerTable存放filtersrc信息
RouteInfoManager方法
1.获取所有集群的信息(无锁)
public byte[] getAllClusterInfo() { ClusterInfo clusterInfoSerializeWrapper = new ClusterInfo(); clusterInfoSerializeWrapper.setBrokerAddrTable(this.brokerAddrTable); clusterInfoSerializeWrapper.setClusterAddrTable(this.clusterAddrTable); return clusterInfoSerializeWrapper.encode(); }
2.删除topic信息(需要写锁)
public void deleteTopic(final String topic) { try { try { this.lock.writeLock().lockInterruptibly(); this.topicQueueTable.remove(topic); } finally { this.lock.writeLock().unlock(); } } catch (Exception e) { log.error("deleteTopic Exception", e); } }
3.获取所有broker的topicList(读锁)
public byte[] getAllTopicList() { TopicList topicList = new TopicList(); try { try { this.lock.readLock().lockInterruptibly(); topicList.getTopicList().addAll(this.topicQueueTable.keySet()); } finally { this.lock.readLock().unlock(); } } catch (Exception e) { log.error("getAllTopicList Exception", e); } return topicList.encode(); }
4.注册broker(写锁)0
public RegisterBrokerResult registerBroker( final String clusterName, final String brokerAddr, final String brokerName, final long brokerId, final String haServerAddr, final TopicConfigSerializeWrapper topicConfigWrapper, final List<String> filterServerList, final Channel channel) { RegisterBrokerResult result = new RegisterBrokerResult(); try { try { this.lock.writeLock().lockInterruptibly(); Set<String> brokerNames = this.clusterAddrTable.get(clusterName); if (null == brokerNames) { brokerNames = new HashSet<String>(); this.clusterAddrTable.put(clusterName, brokerNames); } brokerNames.add(brokerName); boolean registerFirst = false; BrokerData brokerData = this.brokerAddrTable.get(brokerName); if (null == brokerData) { registerFirst = true; brokerData = new BrokerData(clusterName, brokerName, new HashMap<Long, String>()); this.brokerAddrTable.put(brokerName, brokerData); } String oldAddr = brokerData.getBrokerAddrs().put(brokerId, brokerAddr); registerFirst = registerFirst || (null == oldAddr); if (null != topicConfigWrapper && MixAll.MASTER_ID == brokerId) { if (this.isBrokerTopicConfigChanged(brokerAddr, topicConfigWrapper.getDataVersion()) || registerFirst) { ConcurrentMap<String, TopicConfig> tcTable = topicConfigWrapper.getTopicConfigTable(); if (tcTable != null) { for (Map.Entry<String, TopicConfig> entry : tcTable.entrySet()) { this.createAndUpdateQueueData(brokerName, entry.getValue()); } } } } BrokerLiveInfo prevBrokerLiveInfo = this.brokerLiveTable.put(brokerAddr, new BrokerLiveInfo( System.currentTimeMillis(), topicConfigWrapper.getDataVersion(), channel, haServerAddr)); if (null == prevBrokerLiveInfo) { log.info("new broker registerd, {} HAServer: {}", brokerAddr, haServerAddr); } if (filterServerList != null) { if (filterServerList.isEmpty()) { this.filterServerTable.remove(brokerAddr); } else { this.filterServerTable.put(brokerAddr, filterServerList); } } if (MixAll.MASTER_ID != brokerId) { String masterAddr = brokerData.getBrokerAddrs().get(MixAll.MASTER_ID); if (masterAddr != null) { BrokerLiveInfo brokerLiveInfo = this.brokerLiveTable.get(masterAddr); if (brokerLiveInfo != null) { result.setHaServerAddr(brokerLiveInfo.getHaServerAddr()); result.setMasterAddr(masterAddr); } } } } finally { this.lock.writeLock().unlock(); } } catch (Exception e) { log.error("registerBroker Exception", e); } return result; } private boolean isBrokerTopicConfigChanged(final String brokerAddr, final DataVersion dataVersion) { BrokerLiveInfo prev = this.brokerLiveTable.get(brokerAddr); if (null == prev || !prev.getDataVersion().equals(dataVersion)) { return true; } return false; }
5.创建或者更新队列信息,由更新broker方法调用
private void createAndUpdateQueueData(final String brokerName, final TopicConfig topicConfig) { QueueData queueData = new QueueData(); queueData.setBrokerName(brokerName); queueData.setWriteQueueNums(topicConfig.getWriteQueueNums()); queueData.setReadQueueNums(topicConfig.getReadQueueNums()); queueData.setPerm(topicConfig.getPerm()); queueData.setTopicSynFlag(topicConfig.getTopicSysFlag()); List<QueueData> queueDataList = this.topicQueueTable.get(topicConfig.getTopicName()); if (null == queueDataList) { queueDataList = new LinkedList<QueueData>(); queueDataList.add(queueData); this.topicQueueTable.put(topicConfig.getTopicName(), queueDataList); log.info("new topic registerd, {} {}", topicConfig.getTopicName(), queueData); } else { boolean addNewOne = true; Iterator<QueueData> it = queueDataList.iterator(); while (it.hasNext()) { QueueData qd = it.next(); if (qd.getBrokerName().equals(brokerName)) { if (qd.equals(queueData)) { addNewOne = false; } else { log.info("topic changed, {} OLD: {} NEW: {}", topicConfig.getTopicName(), qd, queueData); it.remove(); } } } if (addNewOne) { queueDataList.add(queueData); } } }
6.擦除指定broker的topic的写权限(写锁)
public int wipeWritePermOfBrokerByLock(final String brokerName) { try { try { this.lock.writeLock().lockInterruptibly(); return wipeWritePermOfBroker(brokerName); } finally { this.lock.writeLock().unlock(); } } catch (Exception e) { log.error("wipeWritePermOfBrokerByLock Exception", e); } return 0; } private int wipeWritePermOfBroker(final String brokerName) { int wipeTopicCnt = 0; Iterator<Entry<String, List<QueueData>>> itTopic = this.topicQueueTable.entrySet().iterator(); while (itTopic.hasNext()) { Entry<String, List<QueueData>> entry = itTopic.next(); List<QueueData> qdList = entry.getValue(); Iterator<QueueData> it = qdList.iterator(); while (it.hasNext()) { QueueData qd = it.next(); if (qd.getBrokerName().equals(brokerName)) { int perm = qd.getPerm(); perm &= ~PermName.PERM_WRITE; qd.setPerm(perm); wipeTopicCnt++; } } } return wipeTopicCnt; }
7.注销broker(写锁)
public void unregisterBroker( final String clusterName, final String brokerAddr, final String brokerName, final long brokerId) { try { try { this.lock.writeLock().lockInterruptibly(); BrokerLiveInfo brokerLiveInfo = this.brokerLiveTable.remove(brokerAddr); log.info("unregisterBroker, remove from brokerLiveTable {}, {}", brokerLiveInfo != null ? "OK" : "Failed", brokerAddr ); this.filterServerTable.remove(brokerAddr); boolean removeBrokerName = false; BrokerData brokerData = this.brokerAddrTable.get(brokerName); if (null != brokerData) { String addr = brokerData.getBrokerAddrs().remove(brokerId); log.info("unregisterBroker, remove addr from brokerAddrTable {}, {}", addr != null ? "OK" : "Failed", brokerAddr ); if (brokerData.getBrokerAddrs().isEmpty()) { this.brokerAddrTable.remove(brokerName); log.info("unregisterBroker, remove name from brokerAddrTable OK, {}", brokerName ); removeBrokerName = true; } } if (removeBrokerName) { Set<String> nameSet = this.clusterAddrTable.get(clusterName); if (nameSet != null) { boolean removed = nameSet.remove(brokerName); log.info("unregisterBroker, remove name from clusterAddrTable {}, {}", removed ? "OK" : "Failed", brokerName); if (nameSet.isEmpty()) { this.clusterAddrTable.remove(clusterName); log.info("unregisterBroker, remove cluster from clusterAddrTable {}", clusterName ); } } this.removeTopicByBrokerName(brokerName); } } finally { this.lock.writeLock().unlock(); } } catch (Exception e) { log.error("unregisterBroker Exception", e); } } private void removeTopicByBrokerName(final String brokerName) { Iterator<Entry<String, List<QueueData>>> itMap = this.topicQueueTable.entrySet().iterator(); while (itMap.hasNext()) { Entry<String, List<QueueData>> entry = itMap.next(); String topic = entry.getKey(); List<QueueData> queueDataList = entry.getValue(); Iterator<QueueData> it = queueDataList.iterator(); while (it.hasNext()) { QueueData qd = it.next(); if (qd.getBrokerName().equals(brokerName)) { log.info("removeTopicByBrokerName, remove one broker's topic {} {}", topic, qd); it.remove(); } } if (queueDataList.isEmpty()) { log.info("removeTopicByBrokerName, remove the topic all queue {}", topic); itMap.remove(); } } }
8.根据topic获取broker,filter,以及queue信息
public TopicRouteData pickupTopicRouteData(final String topic) { TopicRouteData topicRouteData = new TopicRouteData(); boolean foundQueueData = false; boolean foundBrokerData = false; Set<String> brokerNameSet = new HashSet<String>(); List<BrokerData> brokerDataList = new LinkedList<BrokerData>(); topicRouteData.setBrokerDatas(brokerDataList); HashMap<String, List<String>> filterServerMap = new HashMap<String, List<String>>(); topicRouteData.setFilterServerTable(filterServerMap); try { try { this.lock.readLock().lockInterruptibly(); List<QueueData> queueDataList = this.topicQueueTable.get(topic); if (queueDataList != null) { topicRouteData.setQueueDatas(queueDataList); foundQueueData = true; Iterator<QueueData> it = queueDataList.iterator(); while (it.hasNext()) { QueueData qd = it.next(); brokerNameSet.add(qd.getBrokerName()); } for (String brokerName : brokerNameSet) { BrokerData brokerData = this.brokerAddrTable.get(brokerName); if (null != brokerData) { BrokerData brokerDataClone = new BrokerData(brokerData.getCluster(), brokerData.getBrokerName(), (HashMap<Long, String>) brokerData .getBrokerAddrs().clone()); brokerDataList.add(brokerDataClone); foundBrokerData = true; for (final String brokerAddr : brokerDataClone.getBrokerAddrs().values()) { List<String> filterServerList = this.filterServerTable.get(brokerAddr); filterServerMap.put(brokerAddr, filterServerList); } } } } } finally { this.lock.readLock().unlock(); } } catch (Exception e) { log.error("pickupTopicRouteData Exception", e); } if (log.isDebugEnabled()) { log.debug("pickupTopicRouteData {} {}", topic, topicRouteData); } if (foundBrokerData && foundQueueData) { return topicRouteData; } return null; }
9.扫描不活跃的broker,该方法用于NameserverController中启用定时器清除不活跃的broker
public void scanNotActiveBroker() { 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()); } } }
10.broker断链时候的处理,该方法主要由BrokerHousekeepingService调用,用于在broker与namesrv的链接断开时进行broker相关信息清除工作, 读锁升级到写锁
public void onChannelDestroy(String remoteAddr, Channel channel) { String brokerAddrFound = null; if (channel != null) { try { try { this.lock.readLock().lockInterruptibly(); Iterator<Entry<String, BrokerLiveInfo>> itBrokerLiveTable = this.brokerLiveTable.entrySet().iterator(); while (itBrokerLiveTable.hasNext()) { Entry<String, BrokerLiveInfo> entry = itBrokerLiveTable.next(); if (entry.getValue().getChannel() == channel) { brokerAddrFound = entry.getKey(); break; } } } finally { this.lock.readLock().unlock(); } } catch (Exception e) { log.error("onChannelDestroy Exception", e); } } if (null == brokerAddrFound) { brokerAddrFound = remoteAddr; } else { log.info("the broker's channel destroyed, {}, clean it's data structure at once", brokerAddrFound); } if (brokerAddrFound != null && brokerAddrFound.length() > 0) { try { try { this.lock.writeLock().lockInterruptibly(); this.brokerLiveTable.remove(brokerAddrFound); this.filterServerTable.remove(brokerAddrFound); String brokerNameFound = null; boolean removeBrokerName = false; Iterator<Entry<String, BrokerData>> itBrokerAddrTable = this.brokerAddrTable.entrySet().iterator(); while (itBrokerAddrTable.hasNext() && (null == brokerNameFound)) { BrokerData brokerData = itBrokerAddrTable.next().getValue(); Iterator<Entry<Long, String>> it = brokerData.getBrokerAddrs().entrySet().iterator(); while (it.hasNext()) { Entry<Long, String> entry = it.next(); Long brokerId = entry.getKey(); String brokerAddr = entry.getValue(); if (brokerAddr.equals(brokerAddrFound)) { brokerNameFound = brokerData.getBrokerName(); it.remove(); log.info("remove brokerAddr[{}, {}] from brokerAddrTable, because channel destroyed", brokerId, brokerAddr); break; } } if (brokerData.getBrokerAddrs().isEmpty()) { removeBrokerName = true; itBrokerAddrTable.remove(); log.info("remove brokerName[{}] from brokerAddrTable, because channel destroyed", brokerData.getBrokerName()); } } if (brokerNameFound != null && removeBrokerName) { Iterator<Entry<String, Set<String>>> it = this.clusterAddrTable.entrySet().iterator(); while (it.hasNext()) { Entry<String, Set<String>> entry = it.next(); String clusterName = entry.getKey(); Set<String> brokerNames = entry.getValue(); boolean removed = brokerNames.remove(brokerNameFound); if (removed) { log.info("remove brokerName[{}], clusterName[{}] from clusterAddrTable, because channel destroyed", brokerNameFound, clusterName); if (brokerNames.isEmpty()) { log.info("remove the clusterName[{}] from clusterAddrTable, because channel destroyed and no broker in this cluster", clusterName); it.remove(); } break; } } } if (removeBrokerName) { Iterator<Entry<String, List<QueueData>>> itTopicQueueTable = this.topicQueueTable.entrySet().iterator(); while (itTopicQueueTable.hasNext()) { Entry<String, List<QueueData>> entry = itTopicQueueTable.next(); String topic = entry.getKey(); List<QueueData> queueDataList = entry.getValue(); Iterator<QueueData> itQueueData = queueDataList.iterator(); while (itQueueData.hasNext()) { QueueData queueData = itQueueData.next(); if (queueData.getBrokerName().equals(brokerNameFound)) { itQueueData.remove(); log.info("remove topic[{} {}], from topicQueueTable, because channel destroyed", topic, queueData); } } if (queueDataList.isEmpty()) { itTopicQueueTable.remove(); log.info("remove topic[{}] all queue, from topicQueueTable, because channel destroyed", topic); } } } } finally { this.lock.writeLock().unlock(); } } catch (Exception e) { log.error("onChannelDestroy Exception", e); } } }
11.打印所有信息,需要读锁
public void printAllPeriodically() { try { try { this.lock.readLock().lockInterruptibly(); log.info("--------------------------------------------------------"); { log.info("topicQueueTable SIZE: {}", this.topicQueueTable.size()); Iterator<Entry<String, List<QueueData>>> it = this.topicQueueTable.entrySet().iterator(); while (it.hasNext()) { Entry<String, List<QueueData>> next = it.next(); log.info("topicQueueTable Topic: {} {}", next.getKey(), next.getValue()); } } { log.info("brokerAddrTable SIZE: {}", this.brokerAddrTable.size()); Iterator<Entry<String, BrokerData>> it = this.brokerAddrTable.entrySet().iterator(); while (it.hasNext()) { Entry<String, BrokerData> next = it.next(); log.info("brokerAddrTable brokerName: {} {}", next.getKey(), next.getValue()); } } { log.info("brokerLiveTable SIZE: {}", this.brokerLiveTable.size()); Iterator<Entry<String, BrokerLiveInfo>> it = this.brokerLiveTable.entrySet().iterator(); while (it.hasNext()) { Entry<String, BrokerLiveInfo> next = it.next(); log.info("brokerLiveTable brokerAddr: {} {}", next.getKey(), next.getValue()); } } { log.info("clusterAddrTable SIZE: {}", this.clusterAddrTable.size()); Iterator<Entry<String, Set<String>>> it = this.clusterAddrTable.entrySet().iterator(); while (it.hasNext()) { Entry<String, Set<String>> next = it.next(); log.info("clusterAddrTable clusterName: {} {}", next.getKey(), next.getValue()); } } } finally { this.lock.readLock().unlock(); } } catch (Exception e) { log.error("printAllPeriodically Exception", e); } }
12.获取系统所有的topic组装成TopicList
public byte[] getSystemTopicList() { TopicList topicList = new TopicList(); try { try { this.lock.readLock().lockInterruptibly(); for (Map.Entry<String, Set<String>> entry : clusterAddrTable.entrySet()) { topicList.getTopicList().add(entry.getKey()); topicList.getTopicList().addAll(entry.getValue()); } if (brokerAddrTable != null && !brokerAddrTable.isEmpty()) { Iterator<String> it = brokerAddrTable.keySet().iterator(); while (it.hasNext()) { BrokerData bd = brokerAddrTable.get(it.next()); HashMap<Long, String> brokerAddrs = bd.getBrokerAddrs(); if (brokerAddrs != null && !brokerAddrs.isEmpty()) { Iterator<Long> it2 = brokerAddrs.keySet().iterator(); topicList.setBrokerAddr(brokerAddrs.get(it2.next())); break; } } } } finally { this.lock.readLock().unlock(); } } catch (Exception e) { log.error("getAllTopicList Exception", e); } return topicList.encode(); }
13.根据cluster获取topicList
public byte[] getTopicsByCluster(String cluster) { TopicList topicList = new TopicList(); try { try { this.lock.readLock().lockInterruptibly(); Set<String> brokerNameSet = this.clusterAddrTable.get(cluster); for (String brokerName : brokerNameSet) { Iterator<Entry<String, List<QueueData>>> topicTableIt = this.topicQueueTable.entrySet().iterator(); while (topicTableIt.hasNext()) { Entry<String, List<QueueData>> topicEntry = topicTableIt.next(); String topic = topicEntry.getKey(); List<QueueData> queueDatas = topicEntry.getValue(); for (QueueData queueData : queueDatas) { if (brokerName.equals(queueData.getBrokerName())) { topicList.getTopicList().add(topic); break; } } } } } finally { this.lock.readLock().unlock(); } } catch (Exception e) { log.error("getAllTopicList Exception", e); } return topicList.encode(); }
阅读全文
0 0
- 第一章 NameServer
- 5.NameServer
- TFS配置NameServer
- 《RocketMq》三、NameServer
- ubuntu nameserver 127.0.1.1
- resolv.conf中的nameserver
- MQ NameServer模块划分
- Centos搭建 TFS Nameserver HA
- Linux 的nameserver-域名服务器
- RocketMQ源码分析之NameServer
- RocketMQ原理——NameServer
- linux系统--nameserver惹得祸
- linux修改nameserver方法(DNS配置)
- TFS(Taobao File System)配置NameServer
- TFS(Taobao File System)配置NameServer
- TFS(Taobao File System)配置NameServer
- rocketmq3.26研究之三NameServer
- RocketMQ初探一:NameServer的作用
- 零基础入门学习Python
- Nginx编译安装
- iOS中使用Fastlane实现自动化打包和发布
- 机器学习利器——决策树和随机森林
- jquery-unslider轮播图
- 第一章 NameServer
- nginx下安装dedecms
- notpad++快捷键
- shiro理论基础
- 常见的框架 优缺点简介
- 国庆中秋双节邮件营销 | 大数据&智能化掀起节日营销新革命
- .net程序员面试
- 强大的curl命令的介绍和一般用法
- [FatFs 学习] SD卡总结-SPI模式