RocketMQ笔记:Namesrv

Namesrv简介


Broker启动时,会向所有的Nameserver注册。

消息生产者发送消息前,先去Nameserver拉取broker服务器地址列表。然后根据负载均衡算法选择一台Broker进行消息发送。

NameServerBroker保持长连接,并每隔30s检测Broker是否存活。

如果检测到Broker宕机,则从路由列表中将其移除。但不会马上通知消息生产者。而是在消息发送端提供容错机制来保证消息发送的高可用性。

NameServer集群之间并不互相通信,路由信息并非是强一致性。

NameServer启动流程


  1. 加载配置文件

    // NamesrvConfig
    final NamesrvConfig namesrvConfig = new NamesrvConfig();
    // NettyServerConfig
    final NettyServerConfig nettyServerConfig = new NettyServerConfig();
    nettyServerConfig.setListenPort(9876);
    if (commandLine.hasOption('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);
            MixAll.properties2Object(properties, nettyServerConfig);
            namesrvConfig.setConfigStorePath(file);
            System.out.printf("load config properties file OK, %s%n", file);
            in.close();
        }
    }
    
    

    NameServerConfig的配置来源有两个:

    • 通过-c指定配置文件路径
    • 使用-- 属性名 属性值来设置,如 --listenPort 9876

    NamesrvConfig

    public class NamesrvConfig {
         
        private String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV));
        private String kvConfigPath = System.getProperty("user.home") + File.separator + "namesrv" + File.separator + "kvConfig.json";
        private String configStorePath = System.getProperty("user.home") + File.separator + "namesrv" + File.separator + "namesrv.properties";
        private String productEnvName = "center";
        private boolean clusterTest = false;
        private boolean orderMessageEnable = false;
    }
    
    • rocketmqHome:rocketmq主目录,配置环境变量
    • kvConfigPath:存储KV配置的默认路径
    • configStorePathnameserver默认配置文件路径
    • orderMessageEnable:是否支持顺序消息

    NettyServerConfig

    public class NettyServerConfig implements Cloneable {
         
        private int listenPort = 8888;
        private int serverWorkerThreads = 8;
        private int serverCallbackExecutorThreads = 0;
        private int serverSelectorThreads = 3;
        private int serverOnewaySemaphoreValue = 256;
        private int serverAsyncSemaphoreValue = 64;
        private int serverChannelMaxIdleTimeSeconds = 120;
    
        private int serverSocketSndBufSize = NettySystemConfig.socketSndbufSize;
        private int serverSocketRcvBufSize = NettySystemConfig.socketRcvbufSize;
        private boolean serverPooledByteBufAllocatorEnable = true;
        private boolean useEpollNativeSelector = false;
    }
    
    • listenPort:监听端口
    • serverWorkerThreadNetty业务线程池线程个数
    • serverCallbackExecutorThreadsNetty公共的线程池线程个数。如果业务类型没有指定线程池,则由public线程池执行
    • serverSelectorThreads:IO线程池线程个数。用于解析请求,然后将任务转发给对应的业务类型,再将结果返回给调用方。
    • serverOnewaySemaphoreValuesend oneway消息请求并发度(Broker
    • serverAsyncSemaphoreValue:异步消息发送的最大并发度(Broker
    • serverChannelMaxIdleTimeSeconds:网络连接的最大空闲时间,如果连接空闲时间操作此数,连接将被关闭
    • serverSocketSndBufSize:网络socket发送缓存区大小,默认64k
    • serverSocketRcvBufSize:网络socket接收缓存区大小,默认64k
    • serverPooledByteBufAllocatorEnableByteBuffer是否开启缓存
    • useEpollNativeSelector:是否启用Epoll IO模型,Linux建议开启
  2. 根据启动属性创建NamesrvController,并初始化改实例。

    public boolean initialize() {
         
    	// 加载KV配置
        this.kvConfigManager.load();
    	// 创建NameServer网络处理对象
        this.remotingServer = new NettyRemotingServer(this.nettyServerConfig, this.brokerHousekeepingService);
    
        this.remotingExecutor =
            Executors.newFixedThreadPool(nettyServerConfig.getServerWorkerThreads(), new ThreadFactoryImpl("RemotingExecutorThread_"));
    
        this.registerProcessor();
    	// 每隔10s扫描一次Broker,移除不激活的Broker
        this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
         
    
            @Override
            public void run() {
         
                NamesrvController.this.routeInfoManager.scanNotActiveBroker();
            }
        }, 5, 10, TimeUnit.SECONDS);
    
        // 每10分钟打印一次KV配置
        this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
         
    
            @Override
            public void run() {
         
                NamesrvController.this.kvConfigManager.printAllPeriodically();
            }
        }, 1, 10, TimeUnit.MINUTES);
    	// 省略部分代码
        return true;
    }
    
  3. 注册钩子函数

    // 注册钩子函数
    Runtime.getRuntime().addShutdownHook(new ShutdownHookThread(log, new Callable<Void>() {
         
        @Override
        public Void call() throws Exception {
         
            // 关闭线程池,释放资源
            controller.shutdown();
            return null;
        }
    }));
    

路由注册和故障剔除


NameServer的主要作用是为消息生产者和消息消费者提供Topi

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值