rocket mq name server,rocketmq源码解析
概述NameServer是一个简单的主题路由注册中心,支持主题和Broker的动态注册和发现。
包括两个主要功能:
Broker管理,NameServer接受Broker集群的注册信息并保存为路由信息的基础数据。然后提供心跳检测机制,检查Broker是否还活着;路由信息管理,每个名称服务器将保存关于代理集群的整个路由信息和用于客户端查询的队列信息。生产者和消费者可以通过名称服务器了解整个代理集群的路由信息,从而传递和消费消息。
集群代理、生产者集群和消费者集群都需要与名称服务器集群通信。
1.生产者集群(Producer cluster ):生产者集群与名称服务器集群中的任意一个建立连接,以了解要发送的主题当前存在于哪个代理主机上,然后与之建立连接,该连接支持多种负载均衡模式发送消息。
注意:消息生产者通过名称服务器集群获得主题的路由信息,包括哪些队列在主题下,这些队列分布在哪个代理上。生产者只向主节点发送消息,所以它只需要与主节点建立连接。
2.消费群。它将首先与名称服务器集群中的任意一个建立连接,以了解要消费的主题当前存在于哪个代理主机和从属主机上,然后它们将建立连接以支持集群消费并广播消费消息。
消息消费者,通过名称服务器集群获取主题的路由信息,并连接到相应的代理来消费消息。请注意,由于主设备和从设备都可以读取消息,因此消费者将与主设备和从设备建立连接。
3.代理集群代理的角色:
接收由生产者发送的消息或消费者消费该消息的请求。主要负责消息的存储、转发和查询,支持主从部署。一个主机可以对应多个从机。主支持读写,从只支持读。一个代理集群由多个主/从组组成。主机可以读写,从机只能读,主机将写入的数据同步到从机。
代理将向集群中的每个名称服务器注册自己的路由信息。每个Broker节点启动时,都会遍历名称服务器列表,与每个名称服务器建立长连接,注册自己的信息,然后定期上报。
4.NameServer集群Topic路由注册中心,支持Broker的动态注册和发现,保存Topic和Borker的关系。
通常是集群部署,但是每个名称服务器不互相通信,每个名称服务器都有完整的路由信息。
总结:NameServer相当于一个NettyServer,处理来自客户端的请求。在RocketMQ学习源代码之前,最好先了解一下Netty和NIO的基本通信流程。
名称服务器1的主要功能。代码模块
主要有三个模块:kvconfig数据存储、处理器通信处理模块和routeinfo路由模块。
Kvconfigmanager是kvConfig模块的核心类,用于将namesrvController指定的kvConfig配置文件(通常为xxx/kvConfig.json)加载到内存中,读取或添加、删除kvConfig记录,持久化内存记录的配置,直到文件打印出所有kvConfig配置。处理器模块DefaultRequestProcessor处理客户端发送的各种请求,比如kv crud,注册元数据和读取元数据。routeinfo模块的RouteInfoManager存储了一些核心元数据,brokerAddrTable,保存了主题的队列信息,也是真正的路由信息。队列包含代理名称和读写队列的数量。TopicQueueTable保存代理信息,包括其名称、集群名称以及主代理和备份代理地址。ClusterAddrTable存储集群信息,包括每个集群中的所有代理名称、BrokerLiveTable活动代理映射表、代理状态信息(包括所有当前存活的代理)以及它们上次报告心跳的时间。filterServerTable代理上用于类模式消息筛选的FilterServer列表在4.4版之后被放弃。以上所有数据都存储在为HashMap保存的内存中,不会持久化。
2.NameServer启动过程NamesrvStartup启动类,逻辑并不复杂,主要有以下两个主要功能。
(1)解析配置文件
填写NameServerConfig和NettyServerConfig的属性值。包括端口号、目录路径、净线程池数量、消息请求并发性等。
(2)根据startup属性,创建NamesrvController的实例,并初始化该实例。名称服务器控制器是名称服务器的核心控制器。
NameServerController中有一个nettyServer和两个调度任务。
NettyServer负责与经纪人、生产商和消费者的网络沟通。定时任务1:每隔10秒扫描一次经纪人,清除死掉的经纪人。定时2:每10分钟打印一次KV配置。3.路由注册RocketMQ采用的策略是在代理节点启动时轮询名称服务器列表。
(1)Broker与每个名称服务器节点建立长连接,并发起注册请求。
(2)为了证明自己是活的,2)Broker节点会向名称服务器报告最新的信息,然后每30秒向名称服务器发送一次心跳包。
心跳包包含代理Id、代理名称、代理地址、代理所属集群的名称等等。
名称服务器独立管理自己的代理元数据副本:
(1)每个名称服务器将维护一个代理表,以动态存储代理信息。
(2)名称服务器收到心跳包后,会更新时间戳,记录这个代理的最新存活时间。
注册的两种情况:
注册:Broker与每个名称服务器节点建立长连接,并发起注册请求。定时心跳:心跳包设计的亮点是每30秒发送到名称服务器。名称服务器的性能优化:
为了提高并发修改代理表的性能,在路由注册操作中引入了读写锁。这一设计亮点允许多个消息生产者并发读取,这确保了发送消息时的高并发性。同时,名称服务器只能处理一个代理心跳包和多个串行心跳包。
这也是读写锁的一个经典使用场景,就是多读少写。
4.路由剔除名称服务器进行路由剔除的两种情况:
主动消除场景:代理正常关闭时,会执行unregisterBroker命令。被动消除场景:名称服务器定期扫描brokerLiveTable,检测上一个心跳包和当前系统之间的时间差。如果时间超过120秒,则需要移除经纪人。3.1主动拒绝的场景名称服务器与代理保持长时间的连接。
正常情况下,如果代理被关闭,它将与名称服务器断开很长一段时间。Netty的通道关闭侦听器将侦听断开事件,然后将删除代理信息。
对于一些日常的操作和维护工作,比如代理升级,RocketMQ提供了一种优雅的方式来消除路由信息。
例如,在升级区段主点之前,您可以首先通过命令行工具禁止此代理的写权限:
当客户机生产者向这个代理的请求发送消息时,它将收到NO_PERMISSION响应,客户机将自动重试其他代理。
观察到该代理中没有流量后,删除该代理。
3.2 rocket MQ在被动拒绝场景下的路由注册是通过broker和NameServer的心跳功能实现的。
当代理启动时,向集群中的所有名称服务器发送心跳,每30秒向所有名称服务器发送心跳。
当服务器收到心跳数据包时,该名称会更新brokerLiveTable缓存中的lastUpdateTimestamp。然后,名称服务器每10秒扫描一次BrokerLiveTable。120秒收不到心跳包就判死刑。名称服务器将删除代理的路由信息,同时关闭nettysocket连接。
在被动排除下,NameServer中有一个调度任务,每10秒扫描一次Broker表。如果代理心跳包的最新时间戳超过当前时间120秒,它也会确定代理无效并将其删除。
5.路由发现路由发现是客户端的行为。这里的委托人主要讲生产者和消费者。
主动刷新场景:
(1)对于生产者来说,只有在发送第一条消息时才能定义主题,所以会根据主题从名称服务器获取路由信息。
(2)对于消费者来说,订阅话题一般是固定的,启动时会拉位置。
被动场景:
定时刷新机制
6.客户端名称服务器选择策略RocketMQ会将用户设置的名称服务器列表设置为NettyRemotingClient类的namesrvAddrList字段。NettyRemotingClient是RocketMQ对Netty的封装,如下:
选择哪个名称服务器也是使用循环的策略。需要注意的是,虽然使用了循环策略,但是在选择了一个名称服务器节点之后,这个名称服务器总是会被首先选择,其他节点只有在与这个名称服务器节点的通信出现异常的情况下才会被选择。
为什么客户端不与所有的名称服务器节点建立连接,而是只选择其中的一个?
通常,有一些配置好的和固定的名称服务器节点,但是客户端的数量可能是数百或数千。为了减少每个名称服务器节点的压力,每个客户端节点从一个随机的名称服务器开始建立连接,然后循环与其中一个名称服务器节点建立连接。
为了保证名称服务器集群中各个节点的负载能够尽可能相对均衡,在选择轮询策略时,每个客户端的初始随机位置是不同的。
nettyremoting client # namesrvIndex
private final atomic integer namesrvIndex=new atomic integer(initValueIndex());
private static int initValueIndex(){
Random r=new Random();
返回math . ABS(r . nextint()% 999)% 999;
}然后每次选择NameServer,namesrvIndex 1后,对namesrvAddrList取模,在数据下标的位置计算,尝试创建连接。成功创建连接后,当前选择的名称服务器地址将被记录在namesrvAddrChoosed字段中:
如果某个名称服务器节点无法创建连接,它将自动重试其他节点。
nettyremoting client # getAndCreateNameserverChannel
7.名称服务器的CAP特性:AP还是CP?那么rocketmq为什么选择自己开发名称服务器而不是使用这些开源组件呢?
事实上,RocketMQ的早期版本,即MetaQ 1.x和MetaQ 2.x,也依赖于Zookeeper。然而,MetaQ 3.x (RocketMQ)摆脱了对ZooKeeper的依赖,转而采用了自己的名称服务器。
RocketMQ的架构设计决定了:
名称服务器只需要一个轻量级的元数据服务器。nameserver只需要保持最终的一致性,不需要像Zookeeper那样的强一致性解决方案,也不需要依赖另一个中间件,从而降低整体维护成本。
对于Zookeeper、Etcd等一致性强的组件,只要将数据写入主节点,内部数据就会通过状态机复制到其他节点。
Zookeeper用Zab协议,etcd用raft协议。
但是,名称服务器节点彼此不通信,因此数据复制是不可能的。
版权归作者所有:原创作品来自博主小二上九8,转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。