RocketMQ源码初识一 NameServer源码

官方doc中描述

名称服务充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的Broker IP列表。多个Namesrv实例组成集群,但相互独立,没有信息交换。

NameServer:NameServer是一个非常简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现。主要包括两个功能:Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活;路由信息管理,每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询的队列信息。然后Producer和Conumser通过NameServer就可以知道整个Broker集群的路由信息,从而进行消息的投递和消费。NameServer通常也是集群的方式部署,各实例间相互不进行信息通讯。Broker是向每一台NameServer注册自己的路由信息,所以每一个NameServer实例上面都保存一份完整的路由信息。当某个NameServer因某种原因下线了,Broker仍然可以向其它NameServer同步其路由信息,Producer,Consumer仍然可以动态感知Broker的路由的信息。

nameServer大概用到的模块

在这里插入图片描述

源码总结

NameServer代码很少,启动时会主要获取配置,设置配置,然后初始化缓存对象,再调用remoting模块创建一个romotingServer,并设置处理请求类为DefaultRequestProcessor

启动romotingServer,会启动一个netty服务,每次接收到请求会交给DefaultRequestProcessor

代码流程图

在这里插入图片描述

源代码

mai方法

NameServer启动入口,实际有用的功能就两行,一个是创建controller,一个是启动controller

public static void main(String[] args) {
    main0(args);
}

public static NamesrvController main0(String[] args) {
    try {
    	//创建controller
        NamesrvController controller = createNamesrvController(args);
        //启动controller
        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

获取启动参数,判断是否要启动,根据参数中的配置,重写配置类,并根据配置类创建NamesrvController对象

public static NamesrvController createNamesrvController(String[] args) throws IOException, JoranException {
    //设置当前MQ的版本
    System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION));
    //构建命令行工具,用来存储支持的参数,和参数的含义
    // 添加 h->help 与n->namesrvAddr
    Options options = ServerUtil.buildCommandlineOptions(new Options());
    // 添加 c->configFile 与 p-> printConfigItem
    commandLine = ServerUtil.parseCmdLine("mqnamesrv", args, buildCommandlineOptions(options), new PosixParser());
    if (null == commandLine) {
        System.exit(-1);
        return null;
    }
    //构建NameServer的配置信息
    final NamesrvConfig namesrvConfig = new NamesrvConfig();
    //构建netty的配置信息
    final NettyServerConfig nettyServerConfig = new NettyServerConfig();
    //netty监听端口 默认9876(-c指定的配置文件中可修改)
    nettyServerConfig.setListenPort(9876);
    //如果启动的时候,传了
    if (commandLine.hasOption('c')) {
        //如果用户传了-c 指定了配置文件路径
        String file = commandLine.getOptionValue('c');
        if (file != null) {
            //加载配置文件
            InputStream in = new BufferedInputStream(new FileInputStream(file));
            properties = new Properties();
            properties.load(in);
            //覆盖属性
            MixAll.properties2Object(properties, namesrvConfig);
            //覆盖netty相关属性
            MixAll.properties2Object(properties, nettyServerConfig);
            namesrvConfig.setConfigStorePath(file);
            System.out.printf("load config properties file OK, %s%n", file);
            in.close();
        }
    }
    //如果传-p 打印所有配置,并退出程序
    if (commandLine.hasOption('p')) {
        InternalLogger console = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_CONSOLE_NAME);
        MixAll.printObjectProperties(console, namesrvConfig);
        MixAll.printObjectProperties(console, nettyServerConfig);
        System.exit(0);
    }

    MixAll.properties2Object(ServerUtil.commandLine2Properties(commandLine), namesrvConfig);
    //环境变量中是否有RocketmqHome属性,没有的话,报错退出
    if (null == namesrvConfig.getRocketmqHome()) {
        System.out.printf("Please set the %s variable in your environment to match the location of the RocketMQ installation%n", MixAll.ROCKETMQ_HOME_ENV);
        System.exit(-2);
    }
    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    JoranConfigurator configurator = new JoranConfigurator();
    configurator.setContext(lc);
    lc.reset();
    //加载日志配置
    configurator.doConfigure(namesrvConfig.getRocketmqHome() + "/conf/logback_namesrv.xml");
    log = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_LOGGER_NAME);
    MixAll.printObjectProperties(log, namesrvConfig);
    MixAll.printObjectProperties(log, nettyServerConfig);
    //创建Controller,将配置对象传进去
    final NamesrvController controller = new NamesrvController(namesrvConfig, nettyServerConfig);
    // remember all configs to prevent discard
    controller.getConfiguration().registerConfig(properties);
    return controller;
}

Options与PosixParser

org.apache.commons.cli下提供的工具类,可自定义命令行参数,可添加支持的命令,可根据输入的命令执行对应的操作

在这里定义了namerServer启动时支持的参数,可根据传入的参数,执行不同的操作

查看执行效果:
1、idea启动时候,在Program arguments中传-h、-p、-c、-n
2、控制台切目录${ROCKETMQ_HOME}/lib下执行

java -Djava.ext.dirs=../lib -cp rocketmq-namesrv-4.7.1.jar org.apache.rocketmq.namesrv.NamesrvStartup -h

传-h的执行结果

usage: mqnamesrv [-c <arg>] [-h] [-n <arg>] [-p]
 -c,--configFile <arg>    Name server config properties file
 -h,--help                Print help
 -n,--namesrvAddr <arg>   Name server address list, eg: 192.168.0.1:9876;192.168.0.2:9876
 -p,--printConfigItem     Print all config item

传-p的执行结果

19:19:35.130 [main] INFO  RocketmqNamesrvConsole - rocketmqHome=
19:19:35.131 [main] INFO  RocketmqNamesrvConsole - kvConfigPath=/root/namesrv/kvConfig.json
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - configStorePath=/root/namesrv/namesrv.properties
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - productEnvName=center
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - clusterTest=false
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - orderMessageEnable=false
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - listenPort=9876
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverWorkerThreads=8
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverCallbackExecutorThreads=0
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverSelectorThreads=3
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverOnewaySemaphoreValue=256
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverAsyncSemaphoreValue=64
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverChannelMaxIdleTimeSeconds=120
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverSocketSndBufSize=65535
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverSocketRcvBufSize=65535
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - serverPooledByteBufAllocatorEnable=true
19:19:35.132 [main] INFO  RocketmqNamesrvConsole - useEpollNativeSelector=false

NamesrvController构造函数

初始化信息,其中最重要的就是RouteInfoManager

public NamesrvController(NamesrvConfig namesrvConfig, NettyServerConfig nettyServerConfig) {
    //naerServer的配置
    this.namesrvConfig = namesrvConfig;
    //netty的配置
    this.nettyServerConfig = nettyServerConfig;
    //kv配置管理
    this.kvConfigManager = new KVConfigManager(this);
    //路由信息管理
    this.routeInfoManager = new RouteInfoManager();
    //检测broker下线服务
    this.brokerHousekeepingService = new BrokerHousekeepingService(this);
    this.configuration = new Configuration(
        log,
        this.namesrvConfig, this.nettyServerConfig
    );
    this.configuration.setStorePathFromConfig(this.namesrvConfig, "configStorePath");
}

RouteInfoManager构造函数

初始化hashMap

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;

public RouteInfoManager() {
    //记录每个topic的配置信息
    this.topicQueueTable = new HashMap<String, List<QueueData>>(1024);
    //记录每个broker的地址,和broker所属集群
    this.brokerAddrTable = new HashMap<String, BrokerData>(128);
    //记录集群名字对应的broker集合
    this.clusterAddrTable = new HashMap<String, Set<String>>(32);
    //记录在线的broker
    this.brokerLiveTable = new HashMap<String, BrokerLiveInfo>(256);
    this.filterServerTable = new HashMap<String, List<String>>(256);
}

start(controller);

public static NamesrvController start(final NamesrvController controller) throws Exception {
    if (null == controller) {
        throw new IllegalArgumentException("NamesrvController is null");
    }
    //初始化
    boolean initResult = controller.initialize();
    if (!initResult) {
        controller.shutdown();
        System.exit(-3);
    }
    //监听关闭钩子
    Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(log, new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            controller.shutdown();
            return null;
        }
    }));
    //启动
    controller.start();
    return controller;
}

初始化controller.initialize

1、创建NettyRemotingServer:用来接收远端请求
2、创建线程池
3、注册处理器,根据不同请求类型,调用对应操作
4、创建定时任务,定期检查过期broker

public boolean initialize() {
    // 从文件中加载kv配置信息
    this.kvConfigManager.load();
    // 初始化netty服务(接收处理远端请求)
    this.remotingServer = new NettyRemotingServer(this.nettyServerConfig, this.brokerHousekeepingService);
    // 处理远程请求线程池
    this.remotingExecutor = Executors.newFixedThreadPool(nettyServerConfig.getServerWorkerThreads(),
        new ThreadFactoryImpl("RemotingExecutorThread_"));
    // 设置netty服务器处理请求的类是DefaultRequestProcessor
    this.registerProcessor();
    // 每隔10秒检查掉线的broker
    this.scheduledExecutorService.scheduleAtFixedRate(NamesrvController.this.routeInfoManager::scanNotActiveBroker,
        5, 10, TimeUnit.SECONDS);
    // 每隔10分钟输出kv配置信息
    this.scheduledExecutorService.scheduleAtFixedRate(NamesrvController.this.kvConfigManager::printAllPeriodically,
        1, 10, TimeUnit.MINUTES);
    // ssl相关配置,此处可以忽略
    if (TlsSystemConfig.tlsMode != TlsMode.DISABLED) {
        ...
    }
    return true;
}

DefaultRequestProcessor

设置netty实际处理请求时,使用DefaultRequestProcessor处理

private void registerProcessor() {
    if (namesrvConfig.isClusterTest()) {

        this.remotingServer.registerDefaultProcessor(
            new ClusterTestRequestProcessor(this, namesrvConfig.getProductEnvName()), this.remotingExecutor);
    } else {
        //处理远端的服务中注册处理类是DefaultRequestProcessor
        this.remotingServer.registerDefaultProcessor(new DefaultRequestProcessor(this), this.remotingExecutor);
    }
}

NettyRemotingServer构造函数(remoting模块)

初始化netty服务相关类

public NettyRemotingServer(final NettyServerConfig nettyServerConfig,
    final ChannelEventListener channelEventListener) {
    super(nettyServerConfig.getServerOnewaySemaphoreValue(), nettyServerConfig.getServerAsyncSemaphoreValue());
    this.serverBootstrap = new ServerBootstrap();
    this.nettyServerConfig = nettyServerConfig;
    //监听器
    this.channelEventListener = channelEventListener;
    int publicThreadNums = nettyServerConfig.getServerCallbackExecutorThreads();
    if (publicThreadNums <= 0) {
        publicThreadNums = 4;
    }
    //发布事件用的线程池
    this.publicExecutor = Executors.newFixedThreadPool(publicThreadNums, new ThreadFactory() {
        private AtomicInteger threadIndex = new AtomicInteger(0);
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "NettyServerPublicExecutor_" + this.threadIndex.incrementAndGet());
        }
    });
    if (useEpoll()) {
        this.eventLoopGroupBoss = new EpollEventLoopGroup(1, new ThreadFactory() {
            private AtomicInteger threadIndex = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, String.format("NettyEPOLLBoss_%d", this.threadIndex.incrementAndGet()));
            }
        });

        this.eventLoopGroupSelector =
            new EpollEventLoopGroup(nettyServerConfig.getServerSelectorThreads(), new ThreadFactory() {
                private AtomicInteger threadIndex = new AtomicInteger(0);
                private int threadTotal = nettyServerConfig.getServerSelectorThreads();

                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, String.format("NettyServerEPOLLSelector_%d_%d", threadTotal,
                        this.threadIndex.incrementAndGet()));
                }
            });
    } else {
        this.eventLoopGroupBoss = new NioEventLoopGroup(1, new ThreadFactory() {
            private AtomicInteger threadIndex = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, String.format("NettyNIOBoss_%d", this.threadIndex.incrementAndGet()));
            }
        });
        this.eventLoopGroupSelector =
            new NioEventLoopGroup(nettyServerConfig.getServerSelectorThreads(), new ThreadFactory() {
                private AtomicInteger threadIndex = new AtomicInteger(0);
                private int threadTotal = nettyServerConfig.getServerSelectorThreads();

                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, String.format("NettyServerNIOSelector_%d_%d", threadTotal,
                        this.threadIndex.incrementAndGet()));
                }
            });
    }
    loadSslContext();
}

scanNotActiveBroker 检查不是活跃的broker

判断在线的broker是否2分钟没有收到更新信息,如果是移除相关信息

public void scanNotActiveBroker() {
    //获取所有在线的broker
    Iterator<Entry<String, BrokerLiveInfo>> it = this.brokerLiveTable.entrySet().iterator();
    while (it.hasNext()) {
        Entry<String, BrokerLiveInfo> next = it.next();
        //获取最后一次更新事件
        long last = next.getValue().getLastUpdateTimestamp();
        //如果超过2分钟没有更新
        if ((last + BROKER_CHANNEL_EXPIRED_TIME) < System.currentTimeMillis()) {
            //关闭管道
            RemotingUtil.closeChannel(next.getValue().getChannel());
            //从live中移除
            it.remove();
            log.warn("The broker channel expired, {} {}ms", next.getKey(), BROKER_CHANNEL_EXPIRED_TIME);
            //移除相关信息
            this.onChannelDestroy(next.getKey(), next.getValue().getChannel());
        }
    }
}

controller.start() 启动controller

public void start() throws Exception {
     //启动netty服务
     this.remotingServer.start();
     if (this.fileWatchService != null) {
         this.fileWatchService.start();
     }
 }

remotingServer.start 启动netty服务

启动netty服务并绑定端口,设置netty相关的处理类

public void start() {
    // netty
    this.defaultEventExecutorGroup =
        new DefaultEventExecutorGroup(nettyServerConfig.getServerWorkerThreads(), new ThreadFactory() {
            private AtomicInteger threadIndex = new AtomicInteger(0);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "NettyServerCodecThread_" + this.threadIndex.incrementAndGet());
            }
        });
    // 前期准备工作,初始化相关类
    prepareSharableHandlers();
    // 构建netty服务
    ServerBootstrap childHandler = this.serverBootstrap.group(this.eventLoopGroupBoss, this.eventLoopGroupSelector)
        .channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class)
        .option(ChannelOption.SO_BACKLOG, 1024).option(ChannelOption.SO_REUSEADDR, true)
        .option(ChannelOption.SO_KEEPALIVE, false).childOption(ChannelOption.TCP_NODELAY, true)
        .childOption(ChannelOption.SO_SNDBUF, nettyServerConfig.getServerSocketSndBufSize())
        .childOption(ChannelOption.SO_RCVBUF, nettyServerConfig.getServerSocketRcvBufSize())
        //设置端口,默认是9876,可从配置中指定
        .localAddress(new InetSocketAddress(this.nettyServerConfig.getListenPort()))
        .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                //处理握手信息(权限和ssl)
                ch.pipeline().addLast(defaultEventExecutorGroup, HANDSHAKE_HANDLER_NAME, handshakeHandler);
                //设置编码和解码
                ch.pipeline().addLast(defaultEventExecutorGroup, encoder, new NettyDecoder(),
                    new IdleStateHandler(0, 0, nettyServerConfig.getServerChannelMaxIdleTimeSeconds()),
                    //连接管理,有连接发生变化时,发送事件
                    connectionManageHandler,
                    //具体处理接收到的请求
                    serverHandler);
            }
        });

    if (nettyServerConfig.isServerPooledByteBufAllocatorEnable()) {
        childHandler.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
    }
    try {
        //绑定端口
        ChannelFuture sync = this.serverBootstrap.bind().sync();
        InetSocketAddress addr = (InetSocketAddress)sync.channel().localAddress();
        this.port = addr.getPort();
    } catch (InterruptedException e1) {
        throw new RuntimeException("this.serverBootstrap.bind().sync() InterruptedException", e1);
    }

    if (this.channelEventListener != null) {
        this.nettyEventExecutor.start();
    }
    this.timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            try {
                NettyRemotingServer.this.scanResponseTable();
            } catch (Throwable e) {
                log.error("scanResponseTable exception", e);
            }
        }
    }, 1000 * 3, 1000);
}

netty接收请求

connectionManageHandler连接管理

连接有状态变化时,发布相应事件

serverHandler 实际处理请求

netty接收到消息

class NettyServerHandler extends SimpleChannelInboundHandler<RemotingCommand> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {
        //接收到消息时触发
        processMessageReceived(ctx, msg);
    }
}

接收到消息,根据类型调用

    public void processMessageReceived(ChannelHandlerContext ctx, RemotingCommand msg) throws Exception {
        final RemotingCommand cmd = msg;
        if (cmd != null) {
            switch (cmd.getType()) {
                case REQUEST_COMMAND:
                    processRequestCommand(ctx, cmd);
                    break;
                case RESPONSE_COMMAND:
                    processResponseCommand(ctx, cmd);
                    break;
                default:
                    break;
            }
        }
    }

processRequestCommand 处理request类型请求

摘取方法里部分代码,processor为初始化controller时设置的DefaultRequestProcessor

if (pair.getObject1() instanceof AsyncNettyRequestProcessor) {
    //异步请求
    AsyncNettyRequestProcessor processor = (AsyncNettyRequestProcessor)pair.getObject1();
    processor.asyncProcessRequest(ctx, cmd, callback);
} else {
    //同步请求
    NettyRequestProcessor processor = pair.getObject1();
    RemotingCommand response = processor.processRequest(ctx, cmd);
    callback.callback(response);
}

DefaultRequestProcessor.processRequest

根据不同的请求方式,返回不同的数据
例如:注册broker,获取topic等等

public RemotingCommand processRequest(ChannelHandlerContext ctx,
    RemotingCommand request) throws RemotingCommandException {
    if (ctx != null) {
        //打印日志
        log.debug("receive request, {} {} {}",
            request.getCode(),
            RemotingHelper.parseChannelRemoteAddr(ctx.channel()),
            request);
    }
    //根据请求类型,做对应操作
    switch (request.getCode()) {
        //添加kv配置
        case RequestCode.PUT_KV_CONFIG:
            return this.putKVConfig(ctx, request);
        //获取kv配置
        case RequestCode.GET_KV_CONFIG:
            return this.getKVConfig(ctx, request);
        //删除kv配置
        case RequestCode.DELETE_KV_CONFIG:
            return this.deleteKVConfig(ctx, request);
        //查询broker版本(心跳,更新broker最后更新时间)
        case RequestCode.QUERY_DATA_VERSION:
            return queryBrokerTopicConfig(ctx, request);
        //注册broker
        case RequestCode.REGISTER_BROKER:
            Version brokerVersion = MQVersion.value2Version(request.getVersion());
            if (brokerVersion.ordinal() >= MQVersion.Version.V3_0_11.ordinal()) {
                return this.registerBrokerWithFilterServer(ctx, request);
            } else {
                return this.registerBroker(ctx, request);
            }
        //取消broker
        case RequestCode.UNREGISTER_BROKER:
            return this.unregisterBroker(ctx, request);
        //根据topic获取topic信息
        case RequestCode.GET_ROUTEINFO_BY_TOPIC:
            return this.getRouteInfoByTopic(ctx, request);
        //获取所有broker和所有集群信息
        case RequestCode.GET_BROKER_CLUSTER_INFO:
            return this.getBrokerClusterInfo(ctx, request);
        case RequestCode.WIPE_WRITE_PERM_OF_BROKER:
            return this.wipeWritePermOfBroker(ctx, request);
        //获取所有topic
        case RequestCode.GET_ALL_TOPIC_LIST_FROM_NAMESERVER:
            return getAllTopicListFromNameserver(ctx, request);
        //删除topic
        case RequestCode.DELETE_TOPIC_IN_NAMESRV:
            return deleteTopicInNamesrv(ctx, request);
        //获取namespace下所有kv
        case RequestCode.GET_KVLIST_BY_NAMESPACE:
            return this.getKVListByNamespace(ctx, request);
        //获取集群下的topic(先获取集群下的broker,然后获取broker下的topic)
        case RequestCode.GET_TOPICS_BY_CLUSTER:
            return this.getTopicsByCluster(ctx, request);
        //获取所有系统的topic
        case RequestCode.GET_SYSTEM_TOPIC_LIST_FROM_NS:
            return this.getSystemTopicListFromNs(ctx, request);
        case RequestCode.GET_UNIT_TOPIC_LIST:
            return this.getUnitTopicList(ctx, request);
        case RequestCode.GET_HAS_UNIT_SUB_TOPIC_LIST:
            return this.getHasUnitSubTopicList(ctx, request);
        case RequestCode.GET_HAS_UNIT_SUB_UNUNIT_TOPIC_LIST:
            return this.getHasUnitSubUnUnitTopicList(ctx, request);
        //更新nameServer配置
        case RequestCode.UPDATE_NAMESRV_CONFIG:
            return this.updateConfig(ctx, request);
        //获取nameServer配置
        case RequestCode.GET_NAMESRV_CONFIG:
            return this.getConfig(ctx, request);
        default:
            break;
    }
    return null;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RocketMQ NameServerRocketMQ 的一个核心组件,主要负责管理 RocketMQ 集群中的各个 Broker 节点的信息,包括 Broker 的名称、IP 地址、状态等信息。在 RocketMQ 集群中,所有的 Broker 都需要向 NameServer 注册,以便 NameServer 能够掌握整个集群的状态信息。 RocketMQ NameServer码位于 `rocketmq-namesrv` 模块中,其主要实现了以下功能: 1. 启动时加载配置文件,包括监听端口、存储路径、集群名称等信息; 2. 处理 Broker 节点的注册、注销请求,维护 Broker 节点的状态信息; 3. 处理 Consumer 节点的心跳请求,维护 Consumer 节点的状态信息; 4. 处理 Topic 的创建、删除请求,维护 Topic 的状态信息; 5. 提供查询 Broker 节点、Topic 等信息的接口。 RocketMQ NameServer 的核心类是 `NamesrvController`,它继承了 Netty 的 `NettyRemotingServer` 类,并实现了 `RequestProcessor` 接口,用于处理来自 Broker 和 Consumer 节点的请求。在 `NamesrvController` 中,还包含了 `RouteInfoManager`、`BrokerHousekeepingService`、`KVConfigManager` 等组件,用于维护集群状态信息和管理配置文件。 RocketMQ NameServer 的启动入口是 `main` 方法,它会加载配置文件并启动 `NamesrvController`。启动后,NameServer 会监听指定端口,等待来自 Broker 和 Consumer 节点的请求,并根据请求类型调用相应的处理方法进行处理。 总之,RocketMQ NameServer 的主要作用是管理整个 RocketMQ 集群的状态信息,确保集群中各个节点的状态始终保持同步。其码实现比较复杂,需要深入理解 RocketMQ 的设计思想和架构原理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值