十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
使用WebClient时的内部细节有哪些,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、成都网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的峡江网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
默认情况下,所有WebClient的实例,公用Reactor.netty.http.HttpResources中包含的全局Reactor -Netty资源,资源这里具体是指事件循环处理线程池(event loop group)和连接管理池(http连接池)。
这是Spring的推荐的模式,因为复用事件循环线程池是并发调优的首选。
全局资源中默认的事件循环处理线程池中包含12个线程。连接池默认支持最大500个连接,并且当达到最大链接后,使用无界队列缓存待获取链接的请求,另外如果超过45000ms还没获取到链接则报超时。
注:由于连接池中链接是不区分域名的,如果有些域名的响应很耗时,则可能一直持有链接不释放,这可能会影响其他域名的请求。
这时,你可以自定义资源,避免使用全局资源:
@Bean
public ReactorResourceFactory resourceFactory() {
ReactorResourceFactory factory = new ReactorResourceFactory();
factory.setUseGlobalResources(false);
return factory;
}
@Bean
public WebClient webClient() {
Function
mapper = client -> { // Further customizations...
};
ClientHttpConnector connector =
new ReactorClientHttpConnector(resourceFactory(), mapper);
return WebClient.builder().clientConnector(connector).build();
}
但是这样会导致不能复用事件处理线程池。
WebClient默认内部使用Netty实现http客户端调用,这里IO线程其实是netty的IO线程,而netty客户端的IO线程内是不建议做耗时操作的,因为IO线程是用来轮训注册到select上的channel的数据的,如果阻塞了,那么其他channel的读写请求就会得不到及时处理。所以如果consumer内逻辑比较耗时,建议从IO线程切换到其他线程来做。
那么如何切换那?可以使用publishOn把IO线程切换到自定义线程池进行处理:
resp.publishOn(Schedulers.elastic())//切换到Schedulers.elastic()对应的线程池进行处理 .onErrorMap(throwable -> { System.out.println("onErrorMap:" + throwable.getLocalizedMessage()); return throwable; }).subscribe(s -> System.out.println("result:" + Thread.currentThread().getName() + " " + s));
与服务端建立链接超时
HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);
WebClient webClient = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
从服务端读取数据超时
HttpClient httpClient = HttpClient.create() .doOnConnected(conn -> conn .addHandlerLast(new ReadTimeoutHandler(10)));
写数据到服务端超时
HttpClient httpClient = HttpClient.create() .doOnConnected(conn -> conn .addHandlerLast(new WriteTimeoutHandler(10)));
从链接池获取链接超时 需要自己重写ReactorResourceFactory
private SupplierconnectionProviderSupplier = () -> { return ConnectionProvider.fixed("webflux", 500,45000);//设置超时时间为45s};
使用WebClient可以便捷的使用Reactor风格的异步调用,但是知其然还要知其所以然。
看完上述内容,你们掌握使用WebClient时的内部细节有哪些的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!