Spring webflux WebFlux控制器返回流量和背压
在Spring WebFlux中,我有一个类似的控制器:Spring webflux WebFlux控制器返回流量和背压,spring-webflux,reactor,Spring Webflux,Reactor,在Spring WebFlux中,我有一个类似的控制器: @RestController @RequestMapping("/data") public class DataController { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public Flux<Data> getData() { return <data from database using reactive dri
@RestController
@RequestMapping("/data")
public class DataController {
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Data> getData() {
return <data from database using reactive driver>
}
}
@RestController
@请求映射(“/data”)
公共类数据控制器{
@GetMapping(products=MediaType.APPLICATION\u JSON\u值)
公共数据{
返回
}
}
主要的缺点是,反应式代码与标准Java代码看起来非常不同,因此通常必然更加复杂。调试也很困难-例如,普通的堆栈跟踪几乎毫无用处(尽管它们是使调试更容易的工具和技术)。注意:我不是spring framework的开发人员,所以欢迎发表任何评论 订阅出版商的具体内容是什么 它是对端口的长期订阅(服务器初始化本身)。因此,
ReactorHttpServer.class
具有以下方法:
@Override
protected void startInternal() {
DisposableServer server = this.reactorServer.handle(this.reactorHandler).bind().block();
setPort(((InetSocketAddress) server.address()).getPort());
this.serverRef.set(server);
}
订阅方是绑定方法,它(据我所知)请求(Long.MAX_值),因此这里没有背压管理
请求处理的重要部分是方法handle(this.reactorHandler)
。reactorHandler
是ReactorHttpHandlerAdapter
的一个实例。堆栈的更上一层(在ReactorHttpHandlerAdapter
的apply
方法中)是DispatcherHandler.class
。此类的java文档以“HTTP请求处理程序/控制器的中央调度程序。调度到已注册的处理程序以处理请求,提供方便的映射工具”开头。它具有中心方法:
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
if (this.handlerMappings == null) {
return createNotFoundError();
}
return Flux.fromIterable(this.handlerMappings)
.concatMap(mapping -> mapping.getHandler(exchange))
.next()
.switchIfEmpty(createNotFoundError())
.flatMap(handler -> invokeHandler(exchange, handler))
.flatMap(result -> handleResult(exchange, result));
}
netyoutbind.send(…)
的一个实现是reactor.netty.channel.ChannelOperations
。对于通量返回的特定情况,此实现在MonoSendMany.class
中管理NIO。该类使用SendManyInner.class
订阅(…),该类通过实现Subscriber
来执行背压管理,而onSubscribe
则执行请求(128)
。我猜Netty内部使用TCP ACK来表示传输成功
所以
什么(如果有的话)提供了背压
。。。是的,例如通过SendManyInner.class
提供背压,但也存在其他实现
在上下文中,我试图评估在这种特定情况下使用SpringWebFlux是否比SpringMVC更有优势
我认为,这绝对值得评估。然而,就性能而言,我猜结果将取决于并发请求的数量,也可能取决于数据的类型。一般来说,Webflux通常是高吞吐量、低延迟情况下的首选,而且我们的环境中通常可以看到更好的硬件利用率。假设您从数据库获取数据,那么使用同样支持反应式的数据库驱动程序可能会获得最佳结果。除了性能,背压管理始终是查看Webflux的一个很好的理由。自从我们采用Webflux以来,我们的数据平台就再也没有稳定性问题了(不要说,没有其他方法可以拥有一个稳定的系统,但在这里,许多问题都是开箱即用的)
作为旁注:我建议仔细查看一下调度器
,我们最近刚刚通过为慢速数据库访问选择合适的调度器,获得了30%的cpu时间
编辑:
参考文件中明确指出:
ServerRequest和ServerResponse是不可变的接口,提供对HTTP请求和响应的JDK 8友好访问。请求和响应都提供针对身体流的反应流背压
@Override
protected Mono<Void> writeWithInternal(Publisher<? extends DataBuffer> publisher) {
return this.response.send(toByteBufs(publisher)).then();
}