使用WebClient时的内部细节有哪些

使用WebClient时的内部细节有哪些,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、成都网站制作、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的峡江网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

WebClient的一些内部细节

默认使用全局资源

默认情况下,所有WebClient的实例,公用Reactor.netty.http.HttpResources中包含的全局Reactor -Netty资源,资源这里具体是指事件循环处理线程池(event loop group)和连接管理池(http连接池)。

这是Spring的推荐的模式,因为复用事件循环线程池是并发调优的首选。

全局资源中默认的事件循环处理线程池中包含12个线程。连接池默认支持最大500个连接,并且当达到最大链接后,使用无界队列缓存待获取链接的请求,另外如果超过45000ms还没获取到链接则报超时。

注:由于连接池中链接是不区分域名的,如果有些域名的响应很耗时,则可能一直持有链接不释放,这可能会影响其他域名的请求。

这时,你可以自定义资源,避免使用全局资源:

@Beanpublic ReactorResourceFactory resourceFactory() {    ReactorResourceFactory factory = new ReactorResourceFactory();    factory.setUseGlobalResources(false);     return factory;}
@Beanpublic WebClient webClient() {
   Function mapper = client -> {        // Further customizations...    };
   ClientHttpConnector connector =            new ReactorClientHttpConnector(resourceFactory(), mapper);
   return WebClient.builder().clientConnector(connector).build(); }

但是这样会导致不能复用事件处理线程池。

默认IO线程执行回调

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 Supplier connectionProviderSupplier = () -> {   return ConnectionProvider.fixed("webflux", 500,45000);//设置超时时间为45s};

使用WebClient可以便捷的使用Reactor风格的异步调用,但是知其然还要知其所以然。

看完上述内容,你们掌握使用WebClient时的内部细节有哪些的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!


分享文章:使用WebClient时的内部细节有哪些
当前URL:http://azwzsj.com/article/jppisd.html