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(在您的情况下为 TestWordSpout
、TestWordCounter
和 TestGlobalCount
-- 也许例如,如果您使用其他库,则取决于这三个中使用的 classes。请注意不支持嵌套的 jar,即包含在 jar 中的 jar 不起作用——为此,您需要首先提取内部 jar 的 classes,然后将这些 classes 直接添加到最终 jar 中。
拓扑结构完全独立于 jar 文件。是的,这是您通过系统指定的 jar 属性。许多人构建一个包含 main
和拓扑定义(通常是静态的但实际上也可以是灵活的)的 jar 的原因是他们提交拓扑而不是像您一样通过 IDE做,但通过命令行 bin/storm
。为此,需要一个包含在 jar 中的入口点 class,该入口点具有组装拓扑结构的主要方法,并且相同的 jar 也用于 class 文件的代码分发,因为它有效非常方便(与提供单个入口点 class 和一个额外的 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(在您的情况下为 TestWordSpout
、TestWordCounter
和 TestGlobalCount
-- 也许例如,如果您使用其他库,则取决于这三个中使用的 classes。请注意不支持嵌套的 jar,即包含在 jar 中的 jar 不起作用——为此,您需要首先提取内部 jar 的 classes,然后将这些 classes 直接添加到最终 jar 中。
拓扑结构完全独立于 jar 文件。是的,这是您通过系统指定的 jar 属性。许多人构建一个包含 main
和拓扑定义(通常是静态的但实际上也可以是灵活的)的 jar 的原因是他们提交拓扑而不是像您一样通过 IDE做,但通过命令行 bin/storm
。为此,需要一个包含在 jar 中的入口点 class,该入口点具有组装拓扑结构的主要方法,并且相同的 jar 也用于 class 文件的代码分发,因为它有效非常方便(与提供单个入口点 class 和一个额外的 jar 文件相比)。