在 Armeria 上使用第三方 http 客户端
Using third party http client on Armeria
我正在探索 Armeria 框架,我想使用 REST 服务。
使用 Armeria WebClient:
WebClient webClient = WebClient.of("http://localhost:9090");
RequestHeaders getJson = RequestHeaders.of(HttpMethod.GET, "/some-service",
HttpHeaderNames.CONTENT_TYPE, "application/json", "SomeHeader", "armeriaTest");
return webClient.execute(getJson).aggregate().thenApply(resp->{
if(HttpStatus.OK.equals(resp.status())) {
return parseBody(resp.contentUtf8());
}else if(HttpStatus.BAD_REQUEST.equals(resp.status())){
throw new IllegalStateException("not exists");
}
throw new RuntimeException("Error");
});
此代码 returns 将异步解析的 CompletionStage,因为如果我在此处执行 join() 或 get() 会导致“java.lang.IllegalStateException:阻塞事件循环,不要这样做。"
我的问题是:如果我想使用第三方 httpclient 库(如 Apache HttpClient)而不是 Web 怎么办?
客户端调用也应该包含在 Future 中吗?
我应该如何管理客户端请求以适应框架方法并避免“阻塞事件循环”问题?
感谢大家!
是的。当您的代码在事件循环线程中为 运行 时,您不应该执行任何阻塞操作。您可以将阻塞操作提交给其他专用于处理阻塞操作的线程池来执行。
如果您在服务器端使用 Armeria,您可以通过 ServiceRequestContext.blockingTaskExecutor()
:
获得一个
Server server = Server
.builder()
.service("/", (ctx, req) -> {
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
// Perform some blocking operations that return a string.
}, ctx.blockingTaskExecutor());
CompletableFuture<String> f2 = f1.thenApply(result -> {
// Transform the result into an HttpResponse.
return HttpResponse.of("Result: %s", result);
});
return HttpResponse.from(f2);
})
.build();
如果你没有在服务器端使用 Armeria,你可以使用你的平台提供的其他 Executor
,或者你甚至可以创建一个新的 ThreadPoolExecutor
专门用于处理阻塞操作。
我正在探索 Armeria 框架,我想使用 REST 服务。 使用 Armeria WebClient:
WebClient webClient = WebClient.of("http://localhost:9090");
RequestHeaders getJson = RequestHeaders.of(HttpMethod.GET, "/some-service",
HttpHeaderNames.CONTENT_TYPE, "application/json", "SomeHeader", "armeriaTest");
return webClient.execute(getJson).aggregate().thenApply(resp->{
if(HttpStatus.OK.equals(resp.status())) {
return parseBody(resp.contentUtf8());
}else if(HttpStatus.BAD_REQUEST.equals(resp.status())){
throw new IllegalStateException("not exists");
}
throw new RuntimeException("Error");
});
此代码 returns 将异步解析的 CompletionStage,因为如果我在此处执行 join() 或 get() 会导致“java.lang.IllegalStateException:阻塞事件循环,不要这样做。"
我的问题是:如果我想使用第三方 httpclient 库(如 Apache HttpClient)而不是 Web 怎么办? 客户端调用也应该包含在 Future 中吗? 我应该如何管理客户端请求以适应框架方法并避免“阻塞事件循环”问题?
感谢大家!
是的。当您的代码在事件循环线程中为 运行 时,您不应该执行任何阻塞操作。您可以将阻塞操作提交给其他专用于处理阻塞操作的线程池来执行。
如果您在服务器端使用 Armeria,您可以通过 ServiceRequestContext.blockingTaskExecutor()
:
Server server = Server
.builder()
.service("/", (ctx, req) -> {
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> {
// Perform some blocking operations that return a string.
}, ctx.blockingTaskExecutor());
CompletableFuture<String> f2 = f1.thenApply(result -> {
// Transform the result into an HttpResponse.
return HttpResponse.of("Result: %s", result);
});
return HttpResponse.from(f2);
})
.build();
如果你没有在服务器端使用 Armeria,你可以使用你的平台提供的其他 Executor
,或者你甚至可以创建一个新的 ThreadPoolExecutor
专门用于处理阻塞操作。