反应堆serial()似乎丢失了事件

时间:2019-05-01 13:51:51

标签: java project-reactor

在一个Flux中,将流并行化,然后再进行序列化,似乎没有一致地强制执行sequence()方法的假定循环性质,并且看来事件可能会结束得远远超出顺序他们实际上是迷路了。这种行为在多次运行中并不一致,有些运行是按顺序进行的,而另一些则变化很大。

我了解事件可能会在某种程度上乱序到达,但是即使在一个简单的示例中,该程度也足以使某些事件延迟到其使用寿命之外。

对于一组固定的数据,这可能是完全可以接受的,但是对于来自Kafka的事件流,它可能会导致难以调试的数据丢失。

在此示例中,在多次运行中,您可能会看到按顺序打印的2-1000中的每个偶数,然后在另一运行中,看到一系列的偶数从2左右开始,最高到十七百,其中一些两位数字永远不会出现在序列中。

我已经改变了并行线程的数量,顺序的预取,添加了publishOn和subscribeOn步骤,但是似乎并没有什么使它变得可预测的。

    Flux.range(1, 5000)
        .parallel(64)
        .runOn(Schedulers.newParallel("test", 64))
        .filter(integer -> integer % 2 == 0)
        .sequential()
        .take(500)
        .doOnNext(System.out::println)
        .blockLast();
  }

当然,在足够长的时间范围内,每个值都会出现,但实际上,某些事件可能会延迟太长时间而无法使用。

轮循并不是完美的选择,但是对我来说,这似乎不是轮循。我在这里做错什么了吗,还是这是一个更深层次的问题?

1 个答案:

答案 0 :(得分:0)

我已经尝试运行您的示例,并且每次我准确得到500个项目时。

您不能指望它会产生可预测的序列,因为处理是并行的,并且您的核心数可能少于此处使用的线程数(64)。某些线程将没有足够的CPU来执行任务,因此,其他线程将因此获胜,take(500)选择中奖号码。

parallel的分发是循环的,但是处理取决于线程调度程序。