nimbus启动
脚本启动逻辑
通过bin/stormnimbus会启动nimbus进程,类似hadoop的jobtracker。
bin/storm是一个python写的脚本,支持jar,kill,nimbus,supervisor,ui,drpc等等命令。
python的入口函数如下
def main():
if len(sys.argv) <= 1:
print_usage()
sys.exit(-1)
global CONFIG_OPTS
config_list, args = parse_config_opts(sys.argv[1:])
parse_config(config_list)
COMMAND = args[0]
ARGS = args[1:]
(COMMANDS.get(COMMAND, unknown_command))(*ARGS)
最后这条语句将根据不同的命令调用其对应的方法,启动nimbus这里调用是
nimbus(klass="backtype.storm.daemon.nimbus"),在nimbus方法内部会调用exec_storm_class(所有命令所调用的方法内部都会调用这个),根据指定的入口类backtype.storm.daemon.nimbus去启动程序。exec_storm_class内部其实就是通过exec执行java 参数 包名.类名 来启动对应的程序。
nimbus的clojure入口
nimbus从脚本中执行的时候,会根据之前传递的backtype.storm.daemon.nimbus这个类,去定位到backtype/storm/daemon/nimbus.clj这个clojure的文件(关于clojure的命名空间与实际文件的映射其实和java中是一样的的),其中-main是nimbus.clj的入口函数,相当c++/java中的main入口。
-main非常简单,如下所示
(defn -main []
(-launch (standalone-nimbus)))
下面将依次分析,standalong-numbus,以及-launch args各自做了些什么。
standalong-numbus是个函数,在这个函数内部是实现INimbus的接口,大致过程是用到了clojure.core.protocols中的reify来定义了匿名的类型实现了java中的package backtype.storm.scheduler这个包中的INimbus这个接口(clojure中接口的对应物称为协议)
下面代码中参数列表中的第一个参数this,是类似c++/java中的类的成员函数的第一个隐藏参数this,也就是通过this确定到底是使用这个协议的哪个实现。
先看standalone-nimbus的代码如下
(defn standalone-nimbus []
(reify INimbus
(prepare [this conf local-dir]
)
(allSlotsAvailableForScheduling [this supervisors topologiestopologies-missing-assignments]
(->> supervisors
(mapcat (fn [^SupervisorDetails s]
(for [p (.getMeta s)]
(WorkerSlot. (.getId s)p))))
set ))
(assignSlots [this topology slots]
)
(getForcedScheduler [this]
nil )
(getHostName [this supervisors node-id]
(if-let [^SupervisorDetails supervisor (get supervisors node-id)]
(.getHost supervisor)))
))
allSlotsAvailableForScheduling 按clojure的语义进行转下,代码如下
(set ((mapcat (fn [^SupervisorDetails s]