部署JAR拓扑时,Storm missing resources文件夹

时间:2016-08-27 11:15:32

标签: java python sbt apache-storm

我正在尝试部署使用MultiLang Bolt(用Python编写)的拓扑:

builder.setBolt("avro-parser", new AvroBolt(), 3).shuffleGrouping("main-kafka-spout");
builder.setBolt("nlp-analyzer", new NLPBolt("/python/analyzer/audio_parser.py"), 2).shuffleGrouping("avro-parser");

我可以毫无问题地提交拓扑,但检查日志文件我看到了这个错误:

java.lang.RuntimeException: Error when launching multilang subprocess

    at org.apache.storm.utils.ShellProcess.launch(ShellProcess.java:89) ~[storm-core-1.0.1.jar:1.0.1]
    at org.apache.storm.task.ShellBolt.prepare(ShellBolt.java:131) ~[storm-core-1.0.1.jar:1.0.1]
    at org.apache.storm.daemon.executor$fn__7953$fn__7966.invoke(executor.clj:792) ~[storm-core-1.0.1.jar:1.0.1]
    at org.apache.storm.util$async_loop$fn__625.invoke(util.clj:482) [storm-core-1.0.1.jar:1.0.1]
    at clojure.lang.AFn.run(AFn.java:22) [clojure-1.7.0.jar:?]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]
Caused by: java.io.IOException: Cannot run program "/usr/bin/python" (in directory "/var/lib/storm/supervisor/stormdist/sintonea-topology-main-22-1472285031/resources"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(Unknown Source) ~[?:1.8.0_91]
    at org.apache.storm.utils.ShellProcess.launch(ShellProcess.java:82) ~[storm-core-1.0.1.jar:1.0.1]
    ... 5 more
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method) ~[?:1.8.0_91]
    at java.lang.UNIXProcess.<init>(Unknown Source) ~[?:1.8.0_91]
    at java.lang.ProcessImpl.start(Unknown Source) ~[?:1.8.0_91]
    at java.lang.ProcessBuilder.start(Unknown Source) ~[?:1.8.0_91]
    at org.apache.storm.utils.ShellProcess

当然,我注意到我在指定的日志跟踪中没有“resources”文件夹:

  

的/ var / lib中/风暴/主管/ stormdist / sintonea-拓扑主22-1472285031 /资源

如果你在该目录中执行“ls”命令,你会看到它:

stormcode.ser  stormconf.ser  stormjar.jar

为什么storm不在该目录中创建资源文件夹?

我在src / main / resources中有两个资源文件夹:

  • 架构:包含avro方案文件
  • python:包含python代码

这些文件夹将复制到根目录中的JAR中,而不是/ resources文件夹中。

怎么可能?我有一个以这种方式使用模式的AvroBolt,并没有给出任何问题(使用DummyBolt而不是MultiLang Bolt测试):

_schema = parser.parse(getClass().getResourceAsStream("/schema/caller_request.avsc"));

修改

我已将资源文件夹移至

  

baseDirectory.value /“multilang”

看完之后:

http://storm.apache.org/releases/current/Creating-a-new-Storm-project.html

现在创建并复制了资源文件夹,但我仍然遇到同样的问题:

Serializer Exception:
/usr/bin/python: can't open file '/resources/python/analyzer/audio_parser.py': [Errno 2] No such file or directory

编辑2

我找到了一种解决方法(在不同级别创建两个资源文件夹):

  1. 在src的父目录中创建一个multilang / resources(一级)。复制python文件夹:{base-directory} / multilang / resources / python / * .py
  2. 保留文件夹src / main / schema:{base-directory} /src/main/resources/schema/caller_request.avsc。
  3. 并将其添加到我的build.sbt:

    unmanagedResourceDirectories in Compile += { baseDirectory.value / "multilang" }
    unmanagedClasspath in Compile += baseDirectory.value / "multilang"
    

    将我的ShellBot设置为(忽略路径中的“resources”或“/”一词):

    NLPBolt nlpBolt = new NLPBolt("python/analyzer/audio_parser.py");
    

    _schema = parser.parse(getClass().getResourceAsStream("/schema/caller_request.avsc"));
    

    它似乎有效,但我不喜欢这个解决方案。有什么想法吗?

    编辑3

    顺便说一下,这段代码:

    import storm
    #from nltk.stem.snowball import SnowballStemmer
    from es_tagger import SpanishTagger
    
    config = utils.load_json('python/analyzer/data/config.json')
    
    class AudioParserBolt(storm.BasicBolt):
    

    产生以下错误:

    Serializer Exception:
    Traceback (most recent call last):
      File "python/analyzer/audio_parser.py", line 27, in <module>
        class AudioParserBolt(storm.BasicBolt):
    AttributeError: 'module' object has no attribute 'BasicBolt'
    

1 个答案:

答案 0 :(得分:2)

所以,这基本上就是我为了让它发挥作用而做的事情:

  1. 创建文件夹$ {basedir} / multilang / resources - &gt;复制内部的python代码。
  2. 从$ {basedir} / src / main / resources中删除python代码,只留下Avro方案。
  3. 添加到build.sbt文件:
  4.   编译中的

    unmanagedResourceDirectories + = {baseDirectory.value /&#34; multilang&#34; }       Compile中的unmanagedClasspath + = baseDirectory.value /&#34; multilang&#34;

    1. https://github.com/apache/storm/blob/master/storm-multilang/python/src/main/resources/resources/storm.py下载storm.py并将其复制/粘贴到$ {basedir} / multilang / resources / python文件夹中。
    2. 在Python代码中,注释或删除任何打印指令(引发解析元组的Java异常,因为打印写入标准输出)。
    3. 如果你的Python进程有点慢(我的是一个NLP进程,并且第一次需要一些设置),请告诉你的拓扑再等一点:
    4.   

      config.put(Config.TOPOLOGY_SUBPROCESS_TIMEOUT_SECS,);

      1. 还有很多试验和错误=)
      2. 任何时候你需要在Python代码中使用外部文件,比如配置文件,就像这样调用它(父目录将是我们之前创建的multilang / resources):

          

        config = utils.load_json(&#39; python / analyzer / data / config.json&#39;)