为什么我的螺栓忘记了它的名字?

时间:2018-03-12 09:59:53

标签: apache-storm

我制作了一个简单的日志记录,但似乎忘记了构造函数中提供的名称。此外,似乎构造函数以某种方式被绕过,因为当我向它添加一些日志代码时,它不会记录任何内容。

Apache Storm在某些时候是否对螺栓做了一些奇怪的事情?

    public class SimpleLoggingBolt extends BaseBasicBolt {
    private static final Logger LOG = LogManager.getRootLogger();
    private static String loggingBoltName;

    public SimpleLoggingBolt(String name) {
        super();
        LOG.info("This does not log anything")
        loggingBoltName = name;
    }

    @Override
    public void execute(Tuple input, BasicOutputCollector collector) {
        LOG.info("Bolt {} received tuple: {}", loggingBoltName, input);
        // Loga "Bolt null received tuple..."
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {}

1 个答案:

答案 0 :(得分:1)

执行bolt的构造函数的JVM与运行execute方法的JVM不同。

当您使用storm jar提交拓扑时,Nimbus会启动一个运行拓扑连接代码的新JVM(使用TopologyBuilder并调用StormSubmitter的部分)。这包括运行bolt的构造函数。我相信这个JVM只是记录到你用来运行storm jar的终端,这就是你没有看到日志的原因。

提交并验证拓扑后,它会被序列化并通过网络发送给运行主管的主机(您运行的计算机storm supervisor)。假设主管被分配来运行您的一个螺栓实例。它将启动一个单独的“worker”JVM,它将运行你的bolt(可能还有一些其他组件)。工作者JVM是实际工作发生的地方,也是运行execute的地方。

所以正在发生的事情是你的静态loggingBoltNamestorm jar JVM中被初始化,bolt被序列化,当它在worker JVM中被反序列化时,静态字段再次为null,因为静态字段未序列化。

如果要保留字段值,则不应将字段声明为static。如果该字段可以序列化,并且不是statictransient,那么一旦在工作程序中反序列化了螺栓,它将保留您在构造函数中设置的值。

以下是一些相关文档https://storm.apache.org/releases/2.0.0-SNAPSHOT/Understanding-the-parallelism-of-a-Storm-topology.html