我有一个 Spring Boot 服务,它使用 WebClient 调用另一个外部服务。外部服务的平均延迟约为 15 ms(通过 Datadog 测量)。但是,当通过我们的服务调用外部 API 时,使用 webClient 调用外部 API 所花费的平均时间远高于该值,约为 65 毫秒。
这是如何调用外部API的示例代码。
public Foo fetchFoo() {
return webClient.get()
.uri(uriBuilder -> uriBuilder
.path(externalAPIEndPoint)
.build())
.retrieve()
.bodyToMono(Foo.class)
.retry(defaultMaxRetry)
.block();
}
造成如此巨大时差的原因是什么?我们可以采取哪些方法来减少所需时间?
造成延误的原因有很多。例如:
延迟原因:
您正在使用的方法
.block();
可能会导致延迟,您可以删除它并继续重试。
对 externalAPIEndpoint 的调用可能会因创建新连接或由于
handshake/TLS
检查而产生网络延迟。这可以通过使用 connection pool
来改进。
retry() 方法也会导致延迟,因为通常重试都有重要的参数,例如重试延迟和重试次数。因此,优化您的重试策略(根据需要)也有助于减少延迟。
我建议的改进:
代码示例:
HttpClient httpClient = HttpClient.create(ConnectionProvider.builder("custom")
.maxConnections(100)
.build());
WebClient client = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
block()
方法,你的代码变成:代码示例
public Mono<Foo> fetchFoo() {
return webClient.get()
.uri(uriBuilder -> uriBuilder.path(externalAPIEndPoint).build())
.retrieve()
.bodyToMono(Foo.class)
.retry(defaultMaxRetry);
}
额外内容(它们可能超出了本文的范围,但也许值得一提):
您还可以添加缓存策略,以提高性能,以防负载流量较高。
您还可以根据特定指标添加自动缩放。