温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-09-18 10:53:27 来源:亿速云 阅读:259 作者:柒染 栏目:编程语言

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

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

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI