我的 Micronaut 应用程序中有两个声明性客户端,我正在以非阻塞方式收集它们的结果(以及一些其他异步方法)。但每隔一段时间,他们就会产生 io.micronaut.http.client.exceptions.ReadTimeoutException: Read Timeout
。也许每 10 个或 20 个请求就会发生一次,对于其中任何一个,但我很确定外部服务不会超时,因为它们速度快且高度可用。
这是我的客户的样子:
@Client("https://foo.bar")
public interface ServiceClient {
@Post("/data/myData")
CompletableFuture<List<ServiceResponse>> getDataAsync(@NonNull @Body ServiceRequest request);
}
这就是我在 @Async
方法中调用它们的方式:
.
.
@Inject
private Provider<ServiceClient> serviceClient;
.
.
@Async
public CompletableFuture<Map<String, Optional<ServiceResponse>>> getDataAsync() {
ServiceRequest request = buildRequest(); // Some method
return serviceClient.get().getDataAsync(request)
.thenApply(this::parseResponse) // Some method
.exceptionally(
ex -> {
LOG.error("Failed to connect to service", ex);
return someDefaultMap;
}
);
}
在我的主要方法中,我得到了声明性客户端+一些其他异步方法的结果,并将它们组合在一起:
CompletableFuture<Map<String, Optional<ServiceResponse>>> servideFuture = getDataAsync();
CompletableFuture<Object> future2 = anotherAsyncMethod();
CompletableFuture<Object> future3 = andAnotherAsyncMethod();
CompletableFuture.allOf(servideFuture, future2, future3).thenApply(it -> {
Map<String, Optional<ServiceResponse>> servieRes = servideFuture.join();
Object future2Res = future2.join();
Object future3Res = future3.join();
// Some aggregation
})
我为我的客户设置了 5 秒超时,这已经足够了,因为我调用的其他服务非常快。我还为我的 I/O 执行器使用缓存类型。这是我的配置:
http:
client:
read-timeout: 5s
executors:
io:
type: cached
最佳答案
我想我发现了问题。由于请求量很大,我的客户似乎正在默认事件循环中等待。我专门为我的声明性客户端定义了一个自定义事件循环,现在它运行得非常稳定。
micronaut:
netty:
event-loops:
default:
num-threads: 3
httpclient:
num-threads: 5
http:
client:
read-timeout: 5s
event-loop-group: httpclient
关于java - 来自 Micronaut 声明式客户端的常量 "Read Timeout"异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72747332/