DBS*_*DBS 6 java project-reactor spring-webflux
我正在使用 Spring Webflux 构建一个 spring boot 应用程序,我想让应用程序完全非阻塞。应用程序本身有一些 REST 端点和需要每隔几秒运行一次的批处理作业。对于批处理作业,我试图Flux.interval(Duration.ofMillis(1000))生成我忽略的长值并运行我的预定作业。
Flux.interval(Duration.ofMillis(1000))
.flatMap(ignore -> doSomething())
.subscribe();
Run Code Online (Sandbox Code Playgroud)
但是一段时间后我收到错误
reactor.core.Exceptions$ErrorCallbackNotImplemented: reactor.core.Exceptions$OverflowException: Could not emit tick 257 due to lack of requests (interval doesn't support small downstream requests that replenish slower than the ticks)
有人能告诉我如何克服这个问题吗?
Mar*_*nyi 13
问题的原因很可能是doSomething()操作花费的时间比指定的 Flux 间隔长,这意味着一段时间后doSomething作业相互重叠并产生背压。因为Flux.interval是一个热源(意味着它不会按需发出信号)并且flatMap有一个默认的并发限制 (256),操作员会不堪重负,这会导致OverflowException.
根据您的要求,此问题有几个潜在的解决方案:
这意味着有时,如果我们已经有很多(256)在进行中,我们会跳过一秒钟并且不会在间隔内安排作业。
Flux.interval(Duration.ofMillis(1000))
.onBackpressureDrop()
.flatMap(ignore -> doSomething())
Run Code Online (Sandbox Code Playgroud)
flatMap并发设置为更高的值这仍然会在一段时间后导致溢出异常,但它会延迟问题的出现(可能不是最佳解决方案)。
Flux.interval(Duration.ofMillis(1000))
.flatMap(ignore -> doSomething(), Integer.MAX_VALUE)
Run Code Online (Sandbox Code Playgroud)
我们从热源切换到冷源,从而消除了溢出的可能性。然而,我们失去了每秒安排一个事件的保证。相反,它们将在上一个作业完成且至少经过 1 秒后按需安排。
Mono.just(1).repeat() // infinite Flux with backpressure
.delayElements(Duration.ofMillis(1000))
.concatMap(ignore -> doSomething())
Run Code Online (Sandbox Code Playgroud)
如果您可以处理重叠作业并在flatMap调用中定义合理的并发级别,您还可以将此解决方案与前一个解决方案结合使用。
| 归档时间: |
|
| 查看次数: |
2283 次 |
| 最近记录: |