Storm源码入口分析:
Storm入口是由Python写的,它负责处理提交命令,通过分析用户提交的命令,调用不同的后台函数来进行处理。
首先在Storm.py当中,由main函数负责执行,一下为main函数代码:
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)
Main函数首先会判断是否有提交的命令,而后,提取出第一个命令参数,和之后的另外的参数。将第一个命令参数与COMMANDS字典内的key值进行匹配,获取value值。这个值就是相对应的处理函数。
举个例子,假设我提交的是这条命令:
Storm jar TopologyName.jar TopologyClassName
Main函数就会获取jar,存入COMMAND变量,剩下的jar包名和Topology主函数名称,存入(ARGS)变量当中。接着COMMAND会与字典COMMANDS里面的key值匹配,得到相应的value值,并让ARGS作为参数传入得到的函数。
(COMMANDS.get(COMMAND,unknown_command))(*ARGS)
这条语句,就是最后的调用。COMMANDS字典里有各种命令-函数的键值对。
COMMANDS = {"jar": jar, "kill": kill, "shell": shell, "nimbus": nimbus, "ui": ui, "logviewer": logviewer,"drpc": drpc, "supervisor": supervisor, "localconfvalue": print_localconfvalue,"remoteconfvalue": print_remoteconfvalue, "repl": repl, "classpath": print_classpath,
"activate": activate, "deactivate": deactivate, "rebalance": rebalance, "help": print_usage,"list": listtopos, "dev-zookeeper": dev_zookeeper, "version": version, "monitor": monitor,"upload-credentials": upload_credentials, "pacemaker": pacemaker, "heartbeats": heartbeats, "blobstore": blobstore,
"get-errors": get_errors, "set_log_level": set_log_level, "kill_workers": kill_workers,node-health-check": healthcheck, "sql": sql}
这些键值对都是对应着Storm里面的各种操作。而我们最初使用jar命令就是提交Topology到Storm系统里面,当Storm接收到命令以后,就会调用jar函数,代码如下面这一段:
def jar(jarfile, klass, *args):
transform_class = confvalue("client.jartransformer.class", [CLUSTER_CONF_DIR])
if (transform_class != None and transform_class != "nil"):
tmpjar = os.path.join(tempfile.gettempdir(), uuid.uuid1().hex+".jar") exec_storm_class("org.apache.storm.daemon.ClientJarTransformerRunner", args=[transform_class, jarfile, tmpjar], fork=True, daemon=False)
exec_storm_class(
klass,
jvmtype="-client",
extrajars=[tmpjar, USER_CONF_DIR, STORM_BIN_DIR],
args=args,
daemon=False,
fork=True,
jvmopts=JAR_JVM_OPTS + ["-Dstorm.jar=" + tmpjar])
os.remove(tmpjar)
else:
exec_storm_class(
klass,
jvmtype="-client",
extrajars=[jarfile, USER_CONF_DIR, STORM_BIN_DIR],
args=args,
daemon=False,
jvmopts=JAR_JVM_OPTS + ["-Dstorm.jar=" + jarfile])
可以看到jar函数会接受一个jar文件命,然后接受它的主类命,这两个东西就是最初main函数获取里面的ARGS参数里面的东西。处理以后,最终调用exec_storm_class()函数执行。
这就是整个Storm系统的入口,无论想如何对Storm进行指令操作,都会经过这样的一条路,只是每个不同的指令得到的调用函数不相同。