如何找出风暴拓扑中没有哪个螺栓?

时间:2019-06-28 18:44:49

标签: java apache-storm

我一直在研究Storm拓扑,但是我遇到了一些元组故障。我怀疑在特定情况下,其中一个螺栓没有通过超时导致这些故障。在Apache Storm API(0.10.0)中,有没有一种方法可以确定哪个螺栓未按预期进行支撑?

假设我们将MySpout,BoltA和BoltB作为此拓扑的组件,并且MySpout会为两个螺栓发出元组,并期望它们在处理元组后会变位。 executeTuple()方法中的BoltA始终在确认,但BoltB仅在收到的偶数上确认。所有具有奇数值的元组都将在发出10分钟后失败。

在这个小样本中,很容易识别失败的流。但是在一个复杂的系统中,我们可以跟踪具有多个螺栓的数十种不同的流,就像在大海捞针中寻找针头一样。有什么聪明的方法可以找到此故障吗?

public class MySpout extends BaseRichSpout {
    protected SpoutOutputCollector collector;
    //...
    @Override
    public void nextTuple() {
        Integer msgId = new Integer((int)(Math.random() * 5000 + 1));
        collector.emit(new Values(msgId), msgId);
    }
    @Override
    public void fail(Object msgId) {
        new Exception("Failed tuple. msgId="+msgId).printStackTrace();
    }
}

public class BoltA extends BaseRichBolt {
    private OutputCollector outputCollector;
    //...
    @Override
    protected void executeTuple(Tuple input) {
        Integer n = (Integer) input.getValues().get(0);
        outputCollector.ack(input);
    }
}

public class BoltB extends BaseRichBolt {
    private OutputCollector outputCollector;
    //...
    @Override
    protected void executeTuple(Tuple input) {
        Integer n = (Integer) input.getValues().get(0);
        if (n%2==0) {
            outputCollector.ack(input);
        }
    }
}

为此“风暴”配置的超时值为10分钟。

<!-- storm config -->
<property>
    <name>topology.enable.message.timeouts</name>
    <value>true</value>
</property>
<property>
    <!-- 10 mins -->
    <name>topology.message.timeout.secs</name>
    <value>600</value>
</property>

这是当元组失败时我们看到的堆栈跟踪。我试图提取元组失败流的一些信息。它没说什么能帮助我的。

java.lang.Exception: Failed tuple. msgId=1234
at MySpout.fail(MySpout.java:127) [myJar.jar:?]
at backtype.storm.daemon.executor$fail_spout_msg.invoke(executor.clj:401) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.daemon.executor$fn$reify__4467.expire(executor.clj:461) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.utils.RotatingMap.rotate(RotatingMap.java:73) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.daemon.executor$fn__4464$tuple_action_fn__4470.invoke(executor.clj:466) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.daemon.executor$mk_task_receiver$fn__4455.invoke(executor.clj:433) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.disruptor$clojure_handler$reify__4029.onEvent(disruptor.clj:58) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:125) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.utils.DisruptorQueue.consumeBatch(DisruptorQueue.java:87) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.disruptor$consume_batch.invoke(disruptor.clj:76) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.daemon.executor$fn__4464$fn__4479$fn__4510.invoke(executor.clj:578) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at backtype.storm.util$async_loop$fn__543.invoke(util.clj:475) [storm-core-0.10.0-beta1.jar:0.10.0-beta1]
at clojure.lang.AFn.run(AFn.java:22) [clojure-1.6.0.jar:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45]

1 个答案:

答案 0 :(得分:0)

喷口不知道是哪个螺栓导致元组失败,这就是为什么在堆栈跟踪中看不到任何东西的原因。

我将使用1.2.2代码进行响应。您可能可以在0.10.0中进行相同的操作,但是该版本是古老的,我不想在其中进行深入研究。

一种调试方法是在提交拓扑时启用Storm的调试日志记录。

Config config = new Config();
config.setDebug(true);
//submit your topology using this Config

当一个元组失败时,您将获得类似

的日志
  

2019-06-29 12:16:09.552 oasdexecutor线程-11-word-executor [16 16] [INFO] SPOUT失败32496024444700129:{:stream“ default”,:values [84 1561716922356 116]}原因:超时MSG-ID:116

然后您可以通过消除来找出哪个螺栓没有拉紧元组。如果您在日志中搜索元组ID(此处为32496024444700129值),则将看到每次传输到该元组的螺栓的日志,例如

  

2019-06-29 12:15:22.356 oasdexecutor Thread-11-word-executor [16 16] [INFO]传输元组[dest:4元组:源:字:16,流:默认,id:{ 32496024444700129 = 5923978744049352856},[84,1561716922356,116]]

这告诉我,元组已转移到任务4。当拓扑启动时,它记录了任务4是哪个螺栓。您还可以在Storm UI中看到它。

  

2019-06-29 12:15:08.801 o.a.s.d.executor main [INFO]正在加载执行者exclaim1:[4 4]

我可以看到任务4确认了元组,所以这不是元组超时的原因

  

2019-06-29 12:15:22.359 o.a.s.d.任务线程17-exclaim1-executor [4 4] [INFO]发射:exclaim1 __ack_ack [32496024444700129 7387867738466240036]

我还可以看到任务4将元组转移到任务8

  

2019-06-29 12:15:22.359 oasdexecutor Thread-17-exclaim1-executor [4 4] [INFO]转移元组[目标:8元组:源:exclaim1:4,流:默认,id:{ 32496024444700129 = 3796756412183316156},[84 !!!]]

然后任务8处理了它

  

2019-06-29 12:15:22.363 oasdexecutor Thread-5-exclaim2-executor [8 8] [INFO]正在处理收到的消息,用于8个元组:源:exclaim1:4,流:默认,id:{32496024444700129 = 3796756412183316156},[84 !!!]

没有日志显示任务8确认了该元组,因此任务8是未正确确认的螺栓。

我去查找日志中的任务8并获取

  

2019-06-29 12:15:08.446 o.a.s.d.executor main [INFO]加载的执行器任务exclaim2:[8 8]

“ exclaim2”是我的拓扑结构中无法正确识别的螺栓。