2.3. JAX-RS 请求处理
2.3.1. 异步 HTTP 请求处理 复制链接链接已复制到粘贴板!
异步请求处理允许您使用非阻塞输入和输出来处理单个 HTTP 请求,如果需要,也可以在单独的线程中处理。
考虑 AJAX 聊天客户端,您要在其中从客户端和服务器推送和拉取。此场景使客户端在服务器的套接字上长时间阻止,等待新的消息。如果同步 HTTP 处理(其中服务器在传入和传出输入和输出上阻塞),则每个客户端连接使用一个单独的线程。这种请求处理模式消耗了大量内存和宝贵的线程资源。
异步处理分隔连接接受和请求处理操作。它分配两个不同的线程:一个用于接受客户端连接;另一个用于处理大量耗时的操作。在这个模型中,容器的工作方式如下:
- 它分配线程接受客户端连接,这是接收器。
- 然后,它将请求交给处理线程,即工作程序。
- 最后,它会释放接收器线程。
结果由 worker 线程发送回客户端。因此,客户端的连接保持开放,从而提高服务器的吞吐量和可扩展性。
2.3.1.1. 异步 NIO 请求处理 复制链接链接已复制到粘贴板!
RESTEasy 的默认异步引擎实施类是 ApacheHttpAsyncClient4Engine
。它在 Apache Http
上构建,后者使用非阻塞 IO 模型内部分配请求。
Components 的 Http
AsyncClient
您可以通过调用 ResteasyClientBuilder
类中的 useAsyncHttpEngine
方法将异步引擎设置为活跃引擎:
2.3.1.2. 服务器异步响应处理 复制链接链接已复制到粘贴板!
在服务器端,异步处理涉及暂停原始请求线程,并在不同的线程中启动请求处理,后者释放原始服务器端线程,以接受其他传入的请求。
2.3.1.2.1. AsyncResponse API 复制链接链接已复制到粘贴板!
JAX-RS 2.0 规范通过两个类添加了异步 HTTP 支持: @Suspended
注释和 AsyncResponse
接口。
将 AsyncResponse
作为参数注入到您的 JAX-RS 方法,可提示 RESTEasy 分离当前正在执行的线程的 HTTP 请求和响应。这样可确保当前线程不会尝试自动处理响应。
AsyncResponse
是回调对象。调用其中一个 restore ()方法
的操作会导致响应发回到客户端,并且终止 HTTP 请求。以下是异步处理的示例:
2.3.1.3. AsyncInvoker Client API 复制链接链接已复制到粘贴板!
同样,在客户端上,异步处理可防止阻止请求线程,因为不需要花时间等待来自服务器的响应。例如,发出请求的线程也可以更新用户界面组件。如果线程被阻止等待响应,用户感知的应用性能将会受到影响。
2.3.1.3.1. 使用将来 复制链接链接已复制到粘贴板!
在下面的代码片段中,get()
方法在 async()
方法上调用,而不是请求。这会将调用机制从同步更改为异步。async()
方法不同步响应,而是返回一个 将来
的对象。当您 调用 get()
方法时,调用会被阻止,直到响应就绪。当响应就绪时,会返回 if .get()
方法。
2.3.1.3.2. 使用 InvocationCallback 复制链接链接已复制到粘贴板!
通过 AsyncInvoker
接口,您可以在异步调用准备好处理时注册回调用的对象。InvocationCallback
接口提供了两种方法: completed()
和 failed()。
当处理成功完成并且收到响应时,会调用 completed()
方法。相反,每当请求处理不成功时,会调用 failed()
方法。