我有一个拓扑结构,例如由1个喷口和4个螺栓组成
spout A -> bolt B -> bolt C -> bolt E
-> bolt D
只有当螺栓B中的某些条件语句为真时,它才会将元组传递给螺栓C和螺栓D.
只有当螺栓C中的某些条件语句为真时,它才会将元组传递给螺栓E.
因此单个元组可能只到达螺栓B或(螺栓C和D)。
我正在使用BaseBasicBolt,据我所知,它会在调用collector.emit后自动执行。
例如,螺栓B中的执行方法如下所示
public class boltB extends BaseBasicBolt {
public void execute(Tuple tuple, BasicOutputCollector collector) {
...some logic goes here
if (response.getCount() > 0) {
collector.emit(new Values(tuple.getString(0)));
}
}
}
因此,如果没有调用collector.emit,我认为spout中的元组失败了,因为我从风暴ui看到几乎所有来自spout的元组都失败了。
在这种情况下,我应该在哪里调用'ack'以便将spout视为失败元组?
答案 0 :(得分:6)
您正在做的事情对于您正在实施的逻辑是正确的。您无需明确调用ack()
。使用BaseBasicBolt
时,每个元组都会在execute()
方法之后由BasicBoltExecutor
执行。对于失败的元组,您应该检查异常。另外,请尝试查看Storm UI,了解每个喷口和螺栓发出/执行/失败的元组中的异常。
答案 1 :(得分:4)
当你有BaseBasicBolt时 - 即使你没有发射任何东西,也会为你完成任务。
BaseBasicBolt实例在BasicBoltExecutor中执行,其实例 execute()方法如下所示:
public void execute(Tuple input) {
_collector.setContext(input);
try {
_bolt.execute(input, _collector);
_collector.getOutputter().ack(input);
} catch(FailedException e) {
if(e instanceof ReportedFailedException) {
_collector.reportError(e);
}
_collector.getOutputter().fail(input);
}
}
因此,为了停止处理元组,只是不执行,在执行调用之后,它将被激活。由于没有更多的螺栓可以在喷口中回叫ack,这将被称为
希望它能回答你的问题