Apache Storm:在不创建 jar 的情况下以编程方式将拓扑提交到远程集群

Apache Storm: Submit Topology programatically to remote cluster without creating jar

这是我第一次使用 Apache Storm,我遇到了以下问题。对于我的应用程序,我要求使用我的应用程序的每个用户的拓扑图都不同,并且每个用户也可以有多个拓扑图。

因此,我萌生了使用拓扑构建器动态创建拓扑图的想法。例如,使用 storm 中的拓扑示例,这将只是:

TopologyBuilder builder = new TopologyBuilder();

builder.setSpout("1", new TestWordSpout(true), 5);
builder.setSpout("2", new TestWordSpout(true), 3);
builder.setBolt("3", new TestWordCounter(), 3)
        .fieldsGrouping("1", new Fields("word"))
        .fieldsGrouping("2", new Fields("word"));
builder.setBolt("4", new TestGlobalCount())
        .globalGrouping("1");

连同以下配置:

Map defaultConf = Utils.readStormConfig();

Map conf = new HashMap();
conf.put(Config.TOPOLOGY_WORKERS, 1);
conf.put(Config.NIMBUS_HOST, "IP to my remote cluster");
conf.put(Config.NIMBUS_THRIFT_PORT, defaultConf.get(Config.NIMBUS_THRIFT_PORT));
conf.put(Config.STORM_THRIFT_TRANSPORT_PLUGIN, defaultConf.get(Config.STORM_THRIFT_TRANSPORT_PLUGIN));

当 运行 此拓扑在本地集群上(没有 nimbus 配置)时,一切正常。

LocalCluster cluster = new LocalCluster();
cluster.submitTopology("mytopology", conf, builder.createTopology());
Utils.sleep(10000);
cluster.shutdown();

但是,当只调用

将拓扑提交到远程集群时
StormSubmitter.submitTopology("mytopology", conf, builder.createTopology());

我得到以下异常:

java.lang.RuntimeException: Must submit topologies using the 'storm' client script so that StormSubmitter knows which jar to upload.

所以,这个异常向我表明 Storm 提交者需要某种 jar。在做了一些研究之后,我发现我必须在我的代码中设置以下 属性 才能以编程方式提交 jar。

System.setProperty("storm.jar", "path/to/jar");

所以这是我的问题:

我必须提交的 jar 的用途是什么?它只是一个包含我所有可用螺栓和喷口的库,但我仍然可以在代码中动态更改它们的顺序,还是部署的 jar 必须真正包含固定拓扑?如果我必须打包一个罐子,这个罐子是进入 System.setProperty 的罐子吗?

PS:我在 Maven 项目中使用 IntelliJ。

如果您将拓扑提交到远程集群,所有使用的 spouts/bolts 的代码(即 class 文件)必须对集群中的所有节点可用。这就是提交到集群的 jar 文件的用途。它必须包含所有这些文件。在内部,Storm 的 Nimbus 会将这个 jar 分发到所有工作节点以使代码可供它们使用。

jar 只需要包含您要使用的一组 classes(在您的情况下为 TestWordSpoutTestWordCounterTestGlobalCount -- 也许例如,如果您使用其他库,则取决于这三个中使用的 classes。请注意不支持嵌套的 jar,即包含在 jar 中的 jar 不起作用——为此,您需要首先提取内部 jar 的 classes,然后将这些 classes 直接添加到最终 jar 中。

拓扑结构完全独立于 jar 文件。是的,这是您通过系统指定的 jar 属性。许多人构建一个包含 main 和拓扑定义(通常是静态的但实际上也可以是灵活的)的 jar 的原因是他们提交拓扑而不是像您一样通过 IDE做,但通过命令行 bin/storm。为此,需要一个包含在 jar 中的入口点 class,该入口点具有组装拓扑结构的主要方法,并且相同的 jar 也用于 class 文件的代码分发,因为它有效非常方便(与提供单个入口点 class 和一个额外的 jar 文件相比)。