不能通过弹簧网反应来表现背压

时间:2017-02-16 03:33:53

标签: java spring project-reactor spring-webflux

我试图使用弹簧网反应来展示背压,就像它在这里用akka所展示的那样 - https://www.youtube.com/watch?v=oS9w3VenDW0 (在28:20到29:20之间观看)。

为了尝试一下,我使用了github https://github.com/bclozel/spring-boot-web-reactive

下面的示例项目

在设置项目后,我在HomeController.java中添加了一个新端点,如下所示:

@RequestMapping(value = "/longflux",produces = "application/stream+json")
public Flux<Long> longFlux(){
    return Flux.interval(Duration.ofMillis(10)).log();
}

现在,如果我尝试卷曲此端点然后使用(CTRL + z)暂停它,则一旦tcp缓冲区被填满并且服务器应该停止发出事件,就应该启动背压。

但是,暂停curl命令后会抛出异常:

2017-02-16 08:49:48.480 ERROR 3500 --- [        timer-1] reactor.Flux.Interval.4                  : onError(reactor.core.Exceptions$OverflowException: Could not emit value 2578 due to lack of requests)
2017-02-16 08:49:48.481 ERROR 3500 --- [        timer-1] reactor.Flux.Interval.4                  : 
reactor.core.Exceptions$OverflowException: Could not emit value 2578 due to lack of requests
    at reactor.core.Exceptions.failWithOverflow(Exceptions.java:151) ~[reactor-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at reactor.core.publisher.FluxInterval$IntervalRunnable.run(FluxInterval.java:98) ~[reactor-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at reactor.core.scheduler.SingleTimedScheduler$TimedPeriodicScheduledRunnable.run(SingleTimedScheduler.java:394) ~[reactor-core-3.0.4.RELEASE.jar:3.0.4.RELEASE]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_121]

我无法理解为什么请求在curl命令暂停后的某个时间终止(在spring-web-reactive实现中),而在akka示例中(如youtube链接中所示)服务器停止发布tcp缓冲区已满的事件。

1 个答案:

答案 0 :(得分:4)

Flux.interval是一个特殊情况,因为它是一个热源,Reactor没有缓冲时间;这意味着如果由于背压导致请求周期缓慢且间隔源产生的速度更快,Reactor将发出错误信号。

您可以使用.onBackpressureDrop()运算符更新此示例,以便在背压情况下丢弃间隔。这应该符合预期。

有很多方法可以说明背压,包括:

  • 使用delay运营商延迟订阅
  • 模拟多个慢速客户端(带宽和延迟)