RocketMQ source code – 4 – NameServer source code
1. Start NameServer with source code
Starting the source code is actually quite simple. First, you go to the official website of RocketMQ, download the source code package, then use idea to open it and start it directly. You will find that the console prompts you to configure an environment variable ROCKETMQ_HOME, so at this time, we directly configure an environment variable RocketMQ in idea_ Home and specify its value as the root path of the current project. For example, my configuration is ROCKETMQ_HOME=D:\java learning \ RocketMQ \ RocketMQ release-4.7.0
[the transfer of external chain pictures fails. The source station may have anti-theft chain mechanism. It is recommended to save the pictures and upload them directly (img-m9WczlSZ-1622875737784)(image\Snipaste_2021-06-05_13-59-41.png)]
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-Nj1njRLk-1622875737796)(image\Snipaste_2021-06-05_13-45-30.png)]
After this configuration, you need to copy the configuration file.
Directly in rocketmq_ Create a new folder conf under the path specified by home, and then log back under the conf directory in the binary package_ namesrv. Copy the XML configuration file to your new folder conf directory.
Finally, just start it directly.
2 NameServer startup process
The fully qualified name of the NameServer startup class is org apache. rocketmq. namesrv. Namesrvstartup, let's start tracking from the main() method of this class to see what has been done during the startup process?
public static void main(String[] args) { // Call the following main0() method to start main0(args); } public static NamesrvController main0(String[] args) { try { // Create NamesrvController, see 2.1 NamesrvController controller = createNamesrvController(args); // Start NamesrvController, see 2.2 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; }
2.1 creating NamesrvController
public static NamesrvController createNamesrvController(String[] args) throws IOException, JoranException { // REMOTING_VERSION_KEY = "rocketmq.remoting.version" saves the version number of the current RocketMQ System.setProperty(RemotingCommand.REMOTING_VERSION_KEY, Integer.toString(MQVersion.CURRENT_VERSION)); //PackageConflictDetect.detectFastjson(); // Command line parameter mqnamesrv parsing Options options = ServerUtil.buildCommandlineOptions(new Options()); commandLine = ServerUtil.parseCmdLine("mqnamesrv", args, buildCommandlineOptions(options), new PosixParser()); if (null == commandLine) { System.exit(-1); return null; } // Create a NameServer profile class object final NamesrvConfig namesrvConfig = new NamesrvConfig(); // Create a netty server configuration file class object final NettyServerConfig nettyServerConfig = new NettyServerConfig(); // Set the communication port number to 9876 nettyServerConfig.setListenPort(9876); // Command line parameter c parsing 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(); } } // Command line parameter p parsing if (commandLine.hasOption('p')) { InternalLogger console = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_CONSOLE_NAME); MixAll.printObjectProperties(console, namesrvConfig); MixAll.printObjectProperties(console, nettyServerConfig); System.exit(0); } // Or command line parameter parsing. Let's look at the main process first MixAll.properties2Object(ServerUtil.commandLine2Properties(commandLine), namesrvConfig); // Determine whether rocketmq is configured_ If the environment variable home is not configured, an error will be reported here 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); } // Log configuration: you can find that the log configuration file is the environment variable rocketmq_ conf directory under home // The following logback_namesrv.xml file, which is fixed 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); // Print log related configuration information MixAll.printObjectProperties(log, namesrvConfig); MixAll.printObjectProperties(log, nettyServerConfig); // Directly new a NamesrvController object final NamesrvController controller = new NamesrvController(namesrvConfig, nettyServerConfig); // remember all configs to prevent discard // Remember all configurations to prevent loss controller.getConfiguration().registerConfig(properties); return controller; }
Summarize the process of this method:
- Parsing the command line parameter mqnamesrv
- Initialize two configuration objects (NamesrvConfig, NettyServerConfig)
- Parsing command line parameter c
- Parse command line parameter p
- Parsing conf/logback_namesrv.xml file and generate log object by applying the specified configuration
- Generate a NamesrvController object based on two configuration objects
- Remember the configuration to prevent loss
It's quite simple to sort out this process. Let's focus on 2 and 6.
2.1.1 initialize the configuration object NamesrvConfig
NamesrvConfig has only one default constructor, but several fields in the class specify default values
public class NamesrvConfig { private static final InternalLogger log = InternalLoggerFactory.getLogger(LoggerName.NAMESRV_LOGGER_NAME); // ROCKETMQ_HOME_PROPERTY = "rocketmq.home.dir" // ROCKETMQ_HOME_ENV = "ROCKETMQ_HOME" // System.getProperty(key,def) will first find the value corresponding to the key in the system. If it is null, then // Return the following def value. In fact, DEF is equivalent to a default value private String rocketmqHome = System.getProperty(MixAll.ROCKETMQ_HOME_PROPERTY, System.getenv(MixAll.ROCKETMQ_HOME_ENV)); // separator = "\" // The default is C: \ users \ administrator \ namesrv \ kvconfig json private String kvConfigPath = System.getProperty("user.home") + File.separator + "namesrv" + File.separator + "kvConfig.json"; // The default is C: \ users \ administrator \ namesrv \ namesrv properties 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; }
When creating an object, all fields have been given initial values
2.1.2 initialize the configuration object NettyServerConfig
NettyServerConfig also has only one default constructor, and several fields in the class specify default values
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; /** * make make install * * * ../glibc-2.10.1/configure \ --prefix=/usr \ --with-headers=/usr/include \ * --host=x86_64-linux-gnu \ --build=x86_64-pc-linux-gnu \ --without-gd */ private boolean useEpollNativeSelector = false; }
When creating an object, all fields have been given initial values