解析S4中node的启动原理(一)

s4启动一个node后,该node 要监听zookeeper是否有新的app。如果有新的app,则该node读取app在zookeeper上的相关信息,并加载app的相关类。最后调用app的init()和start()方法,启动app。整个过程涉及到多个类,所以为了便于讲述,将该部分拆成几部分来谈。

                              一 解析Tools.java

1、Tools.java(package org.apache.s4.tools)是S4启动的一个入口,包含了启动zookeeper,创建cluster,部署application,启动node等命令。例如,./s4 newCluster -c=cluster1 -nbTasks=2 -flp=12000, 就是在s4脚本中调用Tools,然后Tools调用DefineCluster.java创建一个新的cluster。源码中,Tools中的所有命令由一个枚举类型表示。

 enum Task {
        deploy(Deploy.class), node(S4Node.class), zkServer(ZKServer.class), newCluster(DefineCluster.class), adapter(
                null), newApp(CreateApp.class), s4r(Package.class), status(Status.class);

        Class<?> target;

        Task(Class<?> target) {
            this.target = target;
        }

        public void dispatch(String[] args) {
            try {
                Method main = target.getMethod("main", String[].class);
                main.invoke(null, new Object[] { args });
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Cannot dispatch to task [{}]: wrong arguments [{}]", this.name(), Arrays.toString(args));
            }
        }

    }

 

 在Tools的main方法中,首先获取task,由于第一个参数为隐藏的s4ScriptPath,所以task为第二个参数。

 task = Task.valueOf(args[1]);

 然后获取task后的所有参数,如果task不是“node”时,要添加s4ScriptPath,这里暂不管它。当所有参数获取后,调用该task的dispatch方法。在dispatch中,调用task对应类的main方法。taskArgs就是该类main方法的参数。然后task对应的类就启动了。

   List<String> taskArgs = new ArrayList<String>();
        if (!task.name().equals("node")) {
            taskArgs.add(args[0]); // s4 script (only for s4-tools project classes)
        }
        if (args.length > 1) {
            taskArgs.addAll(Arrays.asList(Arrays.copyOfRange(args, 2, args.length)));
        }
        task.dispatch(taskArgs.toArray(new String[] {}));

 

猜你喜欢

转载自ziqiang-1984.iteye.com/blog/1942221
今日推荐