distribution/bin/mqnamesrv中启动NameServer进程的命令:

sh ${ROCKETMQ_HOME}/bin/runserver.sh org.apache.rocketmq.namesrv.NamesrvStartup $@

这行命令执行了runserver.sh,以此启动了NamesrvStartup这个Java类

JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MXX:MaxMetaspaceSize=320m"
choose_gc_options
JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow"
JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages"
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib:${JAVA_HOME}/lib/ext"
#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
JAVA_OPT="${JAVA_OPT} -cp ${CLASSPATH}"$JAVA ${JAVA_OPT} $@

以上命令可以简化为:

java -server -Xms4g -Xmx4g -Xmn2g org.apache.rocketmq.namesrv.NamesrvStartup

这会启动一个JVM进程,执行NamesrcStartup#main()方法,完成NameServer的启动

//创建接收Broker和客户端的网络请求的组件
NamesrvController controller = createNamesrvController(args);

创建出专门用于接收Broker和客户端网络的Controller,其中有NameServer自身运行的配置和Netty的配置:

//NameServer自身运行的配置参数
final NamesrvConfig namesrvConfig = new NamesrvConfig();
//接收网络请求的Netty服务器的配置参数
final NettyServerConfig nettyServerConfig = new NettyServerConfig();
//默认监听请求的端口号:9876
nettyServerConfig.setListenPort(9876);

对于NamesrvConfig的配置:

//获取RocketMQ的环境变量的值
private String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV));
//NameServer存放 K-V 的路径
private String kvConfigPath = System.getProperty("user.home") + File.separator + "namesrv" + File.separator + "kvConfig.json";
//NameServer自己的配置存储路径
private String configStorePath = System.getProperty("user.home") + File.separator + "namesrv" + File.separator + "namesrv.properties";
//生产环境名称,默认center
private String productEnvName = "center";
//是否启动了测试集群,默认false
private boolean clusterTest = false;
//是否支持有序消息,默认false
private boolean orderMessageEnable = false;

对于NettyServerConfig的配置:

//Netty监听的端口号,外面已经设置成9876了
private int listenPort = 8888;
//Netty的工作线程数量,默认8
private int serverWorkerThreads = 8;
//Netty的public线程池的线程数量
private int serverCallbackExecutorThreads = 0;
//Netty的IO线程池中线程数,负责解析网络请求,完事交给work线程处理
private int serverSelectorThreads = 3;
//Broker在使用Netty时,会使用
private int serverOnewaySemaphoreValue = 256;
private int serverAsyncSemaphoreValue = 64;
//一个网络连接空闲超过120s,就会被关闭
private int serverChannelMaxIdleTimeSeconds = 120;//sorket send buffer缓冲区大小
private int serverSocketSndBufSize = NettySystemConfig.socketSndbufSize;
//receive buffer缓冲区大小
private int serverSocketRcvBufSize = NettySystemConfig.socketRcvbufSize;
//ByteBuffer是否开启缓存,默认开启
private boolean serverPooledByteBufAllocatorEnable = true;//是否开启epoll IO模型
private boolean useEpollNativeSelector = false;

现在看,Netty就是接收网络请求的,且监听的端口号是9876。一旦客户端、Broker有请求打过来,就可以处理了。


如果启动NameServer带上了配置文件地址,就基于输入流读取它、并放到那两个核心配置类中:

//如果用mqnamesrc启动时,带上了“-c”,即配置文件的地址,
//就读取配置文件的内容
if (commandLine.hasOption('c')) {String file = commandLine.getOptionValue('c');if (file != null) {//基于输入流从配置文件读取配置,并放到PropertiesInputStream 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();}
}

比如我配置文件nameserver.properties中有一个配置serverWorkerThreads=16,这个配置就会覆盖到核心配置类中去。

然后会把命令行中的配置读出来覆盖到NamesrvConfig、检查环境变量、打印日志等:

//如果带了“-p”,就是把NameServer的所有配置信息都打印出来
if (commandLine.hasOption('p')) {InternalLogger console = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_CONSOLE_NAME);MixAll.printObjectProperties(console, namesrvConfig);MixAll.printObjectProperties(console, nettyServerConfig);System.exit(0);
}//把mqnamesrv命令行中的配置,都读出来放到NamesrvConfig中去
MixAll.properties2Object(ServerUtil.commandLine2Properties(commandLine), namesrvConfig);//如果ROCKETMQ_HOME是空的,就输出一个异常日志
//让我们自己设置一下环境变量
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");//打印NameServer的所有配置信息
log = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_LOGGER_NAME);MixAll.printObjectProperties(log, namesrvConfig);
MixAll.printObjectProperties(log, nettyServerConfig);

等一切配置搞定,就构造出NamesrvController,并将NamesrcConfig、NettyServerConfig这俩核心配置交给它

//构造NamesrvController组件,并把两个核心配置类都交给它
final NamesrvController controller = new NamesrvController(namesrvConfig, nettyServerConfig);// remember all configs to prevent discard
controller.getConfiguration().registerConfig(properties);

意图很明显了,要想启动NameServer,先初始化NamesrvConfig和NettyServerConfig这俩核心配置类,构造NamesrvController时会用得到。

RocketMQ NameServer启动要初始化哪些参数相关推荐

  1. RocketMQ NameServer源码剖析

    概述 NameServer是一个简单的 Topic 路由注册中心,支持 Topic.Broker 的动态注册与发现. 主要包括两个功能: Broker管理 ,NameServer接受Broker集群的 ...

  2. 【Spring】DispatcherServlet的启动和初始化

    使用过SpringMVC的都知道DispatcherServlet,下面介绍下该Servlet的启动与初始化.作为Servlet,DispatcherServlet的启动与Serlvet的启动过程是相 ...

  3. Quartz详解和使用CommandLineRunner在项目启动时初始化定时任务

    文章目录 Quartz介绍 自定义CommandLineRunner类: 创建.更新定时任务 service层 自定义QuartzJobBean 智能调度组件 定时任务实体类: mapper接口: 时 ...

  4. Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源

    Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源 在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spri ...

  5. datanode无法启动_Hadoop DataNode启动和初始化过程

    简介 我们先看DataNode的doc文档的介绍,DataNode是一个类,用于存储一组块,用于DFS部署.单个部署可以有一个或多个DataNode.每个DataNode通信定期与单个NameNode ...

  6. ServletContentLIstener接口演示ServletContext的启动和初始化

    ServletContextListener接口中包含两个方法,一个是contextInitialized()方法, 用来监听ServletContext的启动和初始化:一个是contextDestr ...

  7. linux0.11 init函数,linux0.11启动与初始化

    简单描述Linux0.11的启动与初始化过程. 启动过程中需要关注:IDT, GDT, LDT, TSS, 页表, 堆栈这些数据. 一:启动过程 启动的代码文件为bootsect.s.setup.s. ...

  8. PackageManagerService启动及初始化流程

    PackageManagerService也是有ServerThread启动的,运行在system_process进程. 我们先来看下PackageManagerService是怎么启动的: Pack ...

  9. JVM SandBox源码解析(一):启动时初始化、启动时加载模块、ModuleHttpServlet进行Http路由

    前言 上篇JVM SandBox实现原理详解文章中,主要解析了JVM SandBox的核心实现原理,并且对SandBoxClassLoader和ModuleClassLoader做了源码解析,也解释了 ...

最新文章

  1. python判断二叉树是否为平衡二叉树
  2. AI转型业绩哪家强?联想一季度营收853亿,净利11亿
  3. nrf52840开发套件_nRF52840蓝牙5.0模块有几个突出的优势
  4. Vue.js 状态过渡
  5. 【转】PBR基于物理的渲染
  6. dubbo笔记+源码刨析
  7. ICCV 2019 | 北邮提出高阶注意力模型,大幅改进行人重识别SOTA精度
  8. 前端 CSS 变量简介及基本使用方法
  9. docker 源码分析 三(基于1.8.2版本),NewDaemon启动
  10. 递归下降分析器 c++_专业围观质谱:汇总常见质谱仪专业对比分析!质量分析器直白解剖让你秒懂!...
  11. caffe的python接口学习(2):生成solver文件
  12. 工业循环冷却水处理设计规范_循环冷却水系统及其水处理
  13. 使用一重循环打印乘法口诀
  14. springboot+vue3+微信小程序活动报名系统源码
  15. Hvdc-vsc. 基于vsc的柔性直流输电模型 pscad实现
  16. 2021-05-13 Redis面试题 MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据?
  17. pgMP认证,还是再看看吧!
  18. 【UEFI实战】SlimBootloader中调用FSP
  19. 【android系统】android系统升级流程分析(二)---update升级包分析
  20. MCMC 蒙特卡罗方法 (一)

热门文章

  1. python中嵌套循环的运行原理_python中while嵌套循环的执行流程问题?
  2. Eclipse发布MicroProfile 1.4和2.0
  3. mongo explain分析详解
  4. PHP中对象的深拷贝与浅拷贝
  5. Commonly Hacked Ports
  6. Oracle 用数据泵导入导出数据
  7. 错误:无法作为数据库主体执行,因为主体 dbo 不存在、无法模拟这种类型的主体,或您没有所需的权限...
  8. 使用internal(com.android.internal)和hidden(@hide)APIs – Part 5
  9. chapter_2 索引优先队列
  10. java -IO流_字符流