armeria - 在 Armeria 上使用第三方 http 客户端
问题描述
我正在发现 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");
});
此代码返回将异步解析的 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
专用于处理阻塞操作。
推荐阅读
- python-3.x - 通过分隔符在 Python 中解析文本文件 \r\r\n
- javascript - 将 DTO 发布到 Spring Controller,参数为空
- reactjs - 如何将道具传递给子 React 组件?
- django - 什么时候我们不在 Django Rest Framework 的 ModelSerializer 中使用“__all__”
- java - 使用 Log4j2 减少 Java 堆栈跟踪日志记录
- visual-studio - 是否有一个文件夹我可以删除一个 .vsix 文件,它会导致 Visual Studio 在下次打开时从该文件更新?
- keycloak - JBPM 创建的案例和任务不可见或不可访问
- javascript - CSS 关键帧在开发环境中运行良好,但在生产环境中运行不正常
- python - 包含来自 2 个数据帧的不同值的输出行
- java - 在测试 REST api 时,我得到 200OK,而我应该得到 403