RocketMQ source code -- 4--NameServer startup process

Posted by RJDavison on Mon, 31 Jan 2022 12:48:26 +0100

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:

  1. Parsing the command line parameter mqnamesrv
  2. Initialize two configuration objects (NamesrvConfig, NettyServerConfig)
  3. Parsing command line parameter c
  4. Parse command line parameter p
  5. Parsing conf/logback_namesrv.xml file and generate log object by applying the specified configuration
  6. Generate a NamesrvController object based on two configuration objects
  7. 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

Topics: Java MQ