Previous reading:

[ZooKeeper series] 1.ZooKeeper standalone, pseudo-cluster, and cluster environment construction

2. Use Java to implement the call of ZooKeeper API

In the first two articles of the series, the construction of ZooKeeper environment (including stand-alone version, pseudo cluster and cluster) was introduced, and the creation, deletion and modification of nodes were tested by command line, so that everyone had a preliminary understanding of the construction of ZooKeeper environment and common command line. It also plays a role in building the development environment and production environment of ZooKeeper. Also introduced the use of Java API call, including node increase, delete, change, search. ZooKeeper can also be used to implement naming services, cluster management, distributed locks, load balancing, distributed queues, etc.

In the first two chapters, I emphasized the importance of reading English documents and led you to interpret some official documents. I wanted to convey the idea that ZooKeeper is not as difficult as expected, nor is it that difficult to read official documents. In the following chapters, the official documents are combined to deepen understanding on the basis of actual combat exercises and interpretation of the source code.

Top couplet: say you line you line not line also

Second couplet: say not line not line also not line

Hengpi: Refuse not to accept

Read the source code is exactly the same as this couplet, see you choose the top, or the next couplet!

This article began the source code environment, here we go!

Many people said they would like to read up on github open source projects, but after the code clone, there are always some strange problems, which affect the enthusiasm of learning. ZooKeeper source code learning especially so, many people clone code, reported a variety of errors, prompting less a variety of packages. Asked baidu ZooKeeper source code environment, the search out of the article is really unsatisfactory, some articles wrong was very outrageous. Here I have rebuilt it and will also introduce some of the pits encountered.

Many old people came up with a bunch of fierce operation, from Github download ZooKeeper source code, according to the conventional way to import IDEA, and finally found a variety of packages. At first, I thought ZooKeeper was built using Maven. After carefully checking the version history of ZooKeeper, IT was actually built using Ant. Today, you don’t see Ant projects with Maven or Gradle, so I won’t say much about Ant here.

1 Ant environment construction

The Ant’s official website address: ant.apache.org/bindownload…

After the download and decompression, configure several environment variables as you would configure the JDK:

ANT_HOMT=D:\apache-ant-1.10.7 PATH=%ANT_HOME%/bin CLASSPATH=%ANT_HOME%/libCopy the code

Once configured, test whether Ant is installed successfully. If the following information is displayed, the installation is successful:

Apache Ant(TM) version 1.10.7 compiled on September 1 2019
Copy the code

Ant installation is very similar to JDK installation and configuration, which I won’t cover here.

2 Download the ZooKeeper source code

Source code address: github.com/apache/zook…

At the time of writing this article, the latest version in his Releases list is relex-3.5.6, which we use to build the source environment.

3 Compile the ZooKeeper source code

Switch to the source directory and run Ant Eclipse to compile the project and convert it to eclipse’s project structure.

Four import IDEA

The project has been compiled and transformed into an Eclipse project structure, importing the project as Eclipse.

5 Special Notes

Will source import after the IDEA in the org. Apache. Zookeeper. The Version found in many red alert, less obvious org. Apache. The zookeeper. Version. The Info.

package org.apache.zookeeper.version;

public interface Info {
    int MAJOR = 3;
    int MINOR = 5;
    int MICRO = 6;
    String QUALIFIER = null;
    String REVISION_HASH = "c11b7e26bc554b8523dc929761dd28808913f091";
    String BUILD_DATE = "10/08/2019 20:18 GMT";
}
Copy the code

6 to start the zookeeper

For the single-machine version and the cluster version, there are two startup classes:

  • LAN: ZooKeeperServerMain
  • Cluster: QuorumPeerMain

Here we are only doing standalone testing.

CFG (zoo_sample. CFG) in conf directory. Make a copy and rename it zoo.cfg.

The contents of zoo. CFG are modified (or not modified) to facilitate log query. The dataDir and dataLogDir are set according to their own circumstances.

dataDir=E:\\02private\\1opensource\\zk\\zookeeper\\dataDir
dataLogDir=E:\\02private\\1opensource\\zk\\zookeeper\\dataLogDir
Copy the code

Run the main classes org. Apache. The zookeeper. Server ZooKeeperServerMain, zoo. CFG the full path of the configuration in the Program of the arguments.

ZooKeeperServerMain

Connected to the target VM, address: '127.0.0.1:0', transport: 'socket' log4j:WARN No appenders could be found for logger (org.apache.zookeeper.jmx.ManagedUtil). log4j:WARN Please Initialize the log4j system properly. Log4j: WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.Copy the code

Indicates that the log file cannot be output because the configuration of the log file is incorrect. You need to specify the log file log4j.properties.

-Dlog4j.configuration=file:E:/02private/1opensource/zk/zookeeper/conf/log4j.properties
Copy the code

After the configuration, run ZooKeeperServerMain again. The following log output is displayed:

7 Start the client

The logs obtained by running ZooKeeperServerMain show that the ZooKeeper server has been started and the service address is 127.0.0.1:2181. Start the client to test the connection.

Client startup class for org. Apache. Zookeeper. ZooKeeperMain, configure the following:

/yuanrengu

Lead everybody see below client start source (org. Apache. The zookeeper. ZooKeeperMain). Here to give you my habit of reading source code, many old iron think that reading source code is to follow the code, so there is nothing wrong, but a lot of open source project code is amazing, so a dry view, easy distraction is easy to see. Generally, BASED on a certain function point, I debug from the entrance to find out the “code line” of this function. Just like running a horse ring, I find out the code related to the function and understand the process of parameter transmission. In this way, I can have a more targeted view of the code and eliminate many interfering codes.

7.1 the main

Args contains the same message as in Program Arguments:

7.1.1 ZooKeeperMain

    public ZooKeeperMain(String args[]) throws IOException, InterruptedException {
        // Parse the command line in the argument
        cl.parseOptions(args);
        System.out.println("Connecting to " + cl.getOption("server"));
        // Used to connect to the ZooKeeper server
        connectToZK(cl.getOption("server"));
    }
Copy the code

As you can see from the following figure, after parsing the parameters, you try to connect to 127.0.0.1:2181, the ZooKeeper server. Cl.getoption (“server”) gets 127.0.0.1:2181.

7.1.2 parseOptions

You can clearly know the process of parsing ARGS, mainly from the dimensions of “-server”, “-timeout”, “-r”, “-“.

7.1.3 connectToZK

    protected void connectToZK(String newHost) throws InterruptedException, IOException {
        // Check whether the current ZooKeeper connection is still valid
        // zk.getState().isalive () Check whether the session is valid. If the client is disconnected from Zookeeper, the session is not invalid
        if(zk ! =null && zk.getState().isAlive()) {
            zk.close();
        }

        // newHost is 127.0.0.1:2181
        host = newHost;
        // Determine whether the mode is read-only. The concept of read-only mode was introduced in the previous article
        boolean readOnly = cl.getOption("readonly") != null;
        // Used to determine whether a secure connection is established
        if (cl.getOption("secure") != null) {
            System.setProperty(ZKClientConfig.SECURE_CLIENT, "true");
            System.out.println("Secure connection is enabled");
        }
        zk = new ZooKeeperAdmin(host, Integer.parseInt(cl.getOption("timeout")), new MyWatcher(), readOnly);
    }
Copy the code

Zkclientconfig. SECURE_CLIENT has been marked deprecation:

    /** * Setting this to "true" will enable encrypted client-server communication. */
    @SuppressWarnings("deprecation")
    public static final String SECURE_CLIENT = ZooKeeper.SECURE_CLIENT;
Copy the code

Debug Displays information at key points. You can view the process of setting up a ZooKeeper connection. ZooKeeper API with Java implementation call, this article has described in detail ZooKeeper connection process)

Take a look at some of the key messages below:

Main = new ZooKeeperMain(args); The whole process. The short answer is:

  1. Parse Program Arguments
  2. Connect to the ZooKeeper server

7.2 the main. The run ()

Knock on the blackboard, here comes the big one!

Take a look at the code for run() :

    void run(a) throws CliException, IOException, InterruptedException {
        // cl.getCommand() returns "get"
        if (cl.getCommand() == null) {
            System.out.println("Welcome to ZooKeeper!");

            boolean jlinemissing = false;
            // only use jline if it's in the classpath
            try{ Class<? > consoleC = Class.forName("jline.console.ConsoleReader"); Class<? > completorC = Class.forName("org.apache.zookeeper.JLineZNodeCompleter");

                System.out.println("JLine support is enabled");

                Object console =
                    consoleC.getConstructor().newInstance();

                Object completor =
                    completorC.getConstructor(ZooKeeper.class).newInstance(zk);
                Method addCompletor = consoleC.getMethod("addCompleter",
                        Class.forName("jline.console.completer.Completer"));
                addCompletor.invoke(console, completor);

                String line;
                Method readLine = consoleC.getMethod("readLine", String.class);
                while((line = (String)readLine.invoke(console, getPrompt())) ! =null) { executeLine(line); }}catch (ClassNotFoundException e) {
                LOG.debug("Unable to start jline", e);
                jlinemissing = true;
            } catch (NoSuchMethodException e) {
                LOG.debug("Unable to start jline", e);
                jlinemissing = true;
            } catch (InvocationTargetException e) {
                LOG.debug("Unable to start jline", e);
                jlinemissing = true;
            } catch (IllegalAccessException e) {
                LOG.debug("Unable to start jline", e);
                jlinemissing = true;
            } catch (InstantiationException e) {
                LOG.debug("Unable to start jline", e);
                jlinemissing = true;
            }

            if (jlinemissing) {
                System.out.println("JLine support is disabled");
                BufferedReader br =
                    new BufferedReader(new InputStreamReader(System.in));

                String line;
                while((line = br.readLine()) ! =null) { executeLine(line); }}}else {
            // Process the parameters passed in
            processCmd(cl);
        }
        System.exit(exitCode);
    }
Copy the code

ProcessCmd (CL); Cl contains the following information:

processCmd(MyCommandOptions co)
processZKCmd(MyCommandOptions co)

org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /yuanrengu

Thus lead everybody dubug again org. Apache. The zookeeper. ZooKeeperMain, as I said above, read the source code to do see the effect is very small, can only help debug carding process and way of thinking, also can know what changes have taken place in the process of parameter passing.

Warm prompt

Above we introduced the source environment construction process, run run the main classes org. Apache. Zookeeper. Server ZooKeeperServerMain start the zookeeper server, Run org. Apache. Zookeeper. ZooKeeperMain connect server.

Read the source code is best to move (debug) to read, so that the code is alive, dry look at the code like stagnant water, easy to let a person boring!

Everyone operates in different ways and may encounter different problems. If you encounter any problems during the construction process, you can leave a message in the comment section.