我有一个关于Spring FrameworkWebClient
的问题
在我的应用程序中,我需要做许多类似的API调用,有时我需要更改调用中的头(身份验证令牌)。所以问题来了,这两个选择中哪一个更好:
1.要为所有传入MyService.class的请求创建一个WebClient,请将其设置为private final
字段,如以下代码所示:
private final WebClient webClient = WebClient.builder()
.baseUrl("https://another_host.com/api/get_inf")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.build();
字符串
这里又出现了另一个问题:WebClient
是线程安全的吗?(因为服务被许多线程使用)
1.为每个新传入服务类的请求创建新的WebClient。
我想提供最高的性能并以正确的方式使用它,但我不知道WebClient
在其中如何工作,以及它期望如何使用。
- 谢谢-谢谢
2条答案
按热度按时间mrfwxfqh1#
这里关于
WebClient
的两个关键问题:1.它的HTTP资源(连接、缓存等)由底层库管理,由
ClientHttpConnector
引用,您可以在WebClient
上配置WebClient
是不可变的考虑到这一点,您应该尝试在应用程序中重用相同的
ClientHttpConnector
,因为这将共享连接池-这可以说是性能最重要的事情。这意味着您应该尝试从同一个WebClient.create()
调用派生所有WebClient
示例。Spring Boot
通过为您创建和配置一个WebClient.Builder
bean来帮助您实现这一点,您可以将其注入应用的任何位置。因为
WebClient
* 是 * 不可变的所以是线程安全的。WebClient
用于React式环境,在这种环境中,没有任何东西与特定线程绑定(这并不意味着您不能在传统的Servlet应用程序中使用)。如果您想更改请求的方式,有几种方法可以实现:
在构建器阶段进行配置
字符串
按请求配置
型
在现有客户端示例中新建一个客户端示例
型
2ic8powd2#
根据我的经验,如果您在无法控制的服务器上调用外部API,则根本不要使用WebClient,或者在关闭池机制的情况下使用它。连接池带来的任何性能增益都被内置在(默认reactor-netty)库中的假设所严重地超过,当远程主机突然终止另一个API调用时,这些假设将导致一个API调用的随机错误。在某些情况下,您甚至不知道错误发生在哪里,因为调用都是从共享工作线程进行的。
我犯了使用WebClient的错误,因为RestTemplate的文档说它将来会被弃用。事后看来,我会使用常规的HttpClient或Apache Commons HttpClient,但如果你和我一样,已经用WebClient实现了,你可以通过如下方式创建WebClient来关闭池:
字符串