Apache Storm:Ack无法正常工作

时间:2015-08-17 21:34:10

标签: java apache-storm

我正在尝试实现有保证的消息处理,但是没有调用Spout上的ack或fail方法。

我正在传递带有spout的消息ID对象。 我用每个螺栓传递元组并在每个螺栓中调用collector.ack(元组)。

问题 ack或者失败没有被调用,我无法理解为什么?

这是一个缩短的代码示例。

使用BaseRichSpout发布代码

public void nextTuple() {
    for( String usage : usageData ) {
    .... further code ....

    String msgID = UUID.randomUUID().toString()
                    + System.currentTimeMillis();

    Values value = new Values(splitUsage[0], splitUsage[1],
                    splitUsage[2], msgID);
    outputCollector.emit(value, msgID);
   }
}

@Override
public void ack(Object msgId) {
    this.pendingTuples.remove(msgId);
    LOG.info("Ack " + msgId);
}

@Override
public void fail(Object msgId) {
    // Re-emit the tuple
    LOG.info("Fail " + msgId);
    this.outputCollector.emit(this.pendingTuples.get(msgId), msgId);
}

使用BaseRichBolt的Bolt代码

@Override
public void execute(Tuple inputTuple) {

this.outputCollector.emit(inputTuple, new Values(serverData, msgId));

this.outputCollector.ack(inputTuple);
}

Final Bolt

@Override
public void execute(Tuple inputTuple) {
  ..... Simply reports does not emit .....
  this.outputCollector.ack(inputTuple);

}

1 个答案:

答案 0 :(得分:2)

ack不起作用的原因是在喷口中使用for循环。将其更改为发射下方的计数器循环版本,它可以正常工作。

示例

        index++;
        if (index >= dataset.size()) {
            index = 0;
        }

此外还要感谢邮件列表信息。 因为Spout在单个线程上运行并且将在for循环中阻塞,因为下一个元组将不会返回,因此它将永远无法调用ACK方法。