Apache storm 为什么我不应该在spoute.nextTuple()中循环或阻塞

Apache storm 为什么我不应该在spoute.nextTuple()中循环或阻塞,apache-storm,Apache Storm,我看到许多代码片段,其中在Spout.nextTuple()中使用了一个循环(例如,读取整个文件并为每行发出一个元组): 这段代码似乎是直截了当的,但是,有人告诉我应该不要在nextTuple()内循环。问题是为什么?执行喷口时,它在单个线程中运行。此线程“永远”循环并具有多个职责: 调用speut.nextTuple() 检索“确认”并对其进行处理 检索“失败”并处理它们 超时元组 要实现这一点,关键是不要在nextTuple()中“永远”(即循环或块)停留,而是在向系统发出元组后返回(或者如

我看到许多代码片段,其中在
Spout.nextTuple()
中使用了一个循环(例如,读取整个文件并为每行发出一个元组):


这段代码似乎是直截了当的,但是,有人告诉我应该不要在
nextTuple()内循环。问题是为什么?

执行喷口时,它在单个线程中运行。此线程“永远”循环并具有多个职责:

  • 调用speut.nextTuple()
  • 检索“确认”并对其进行处理
  • 检索“失败”并处理它们
  • 超时元组
  • 要实现这一点,关键是不要在
    nextTuple()
    中“永远”(即循环或块)停留,而是在向系统发出元组后返回(或者如果无法发出元组,则返回,但不要阻止)。否则,喷口无法正常工作nextTuple()。因此,在处理确认/失败消息等之后,对
    nextTuple()
    的下一次调用会很快发生

    因此,在对
    nextTuple()
    的一次调用中发出多个元组也被认为是不好的做法。只要代码停留在
    nextTuple()
    ,喷口线程就不能(例如)对传入的ACK做出反应。这可能会导致不必要的超时,因为无法及时处理ACK

    最佳实践是为对
    nextTuple()
    的每次调用发出一个元组。如果没有可发射的元组,则应返回(不发射),不要等到元组可用

    public void nextTuple() {
        // do other stuff here
    
        // reader might be BufferedReader that is initialized in open()
        String str;
        while((str = reader.readLine()) != null) {
            _collector.emit(new Values(str));
        }
    
        // do some more stuff here
    }