Web Services 泽西岛ws 2.0 @暂停AsyncResponse,它做什么?

pbgvytdp  于 2022-11-15  发布在  其他
关注(0)|答案(3)|浏览(185)

我正在分析一些jersey 2.0代码,我对以下方法的工作原理有一个疑问:

@Stateless
  @Path("/mycoolstuff")
  public class MyEjbResource {
    …
    @GET
    @Asynchronous //does this mean the method executes on child thread ?
    public void longRunningOperation(@Suspended AsyncResponse ar) {
      final String result = executeLongRunningOperation();
      ar.resume(result);
    }

    private String executeLongRunningOperation() { … }
  }

假设我在网页浏览器中输入www.mysite/mycoolstuff,这将执行该方法,但我不明白asyncResponse用于@Asynchronous注解。从浏览器中,我如何注意到它的异步性?删除注解有什么区别?还有在阅读documentation后挂起的注解,我不清楚它的用途。
这个@Asynchronous注解只是告诉程序在一个新线程上执行这个方法吗?2它是一个执行“新线程(.....)”的方便方法吗?
更新:这个注解减轻了服务器对请求处理线程的挂起。吞吐量可以更好。无论如何,从官方的docs
默认情况下,服务器上的请求处理工作在同步处理模式下,这意味着请求的客户端连接在单个I/O容器线程中处理。一旦处理请求的线程返回到I/O容器,容器可以安全地假设请求处理完成并且可以安全地释放客户端连接,包括与该连接相关联的所有资源。此模型通常足以处理处理资源方法执行所需时间相对较短的请求。但是,如果已知资源方法执行需要很长时间来计算结果,则应使用服务器端异步处理模型。在此模型中,当请求处理线程返回时,处理传入请求I/O容器可能不再假定客户端连接可以被安全地关闭。相反,需要公开用于显式挂起、恢复和关闭客户端连接的工具。注意,使用服务器端异步处理模型不会改善客户端感知的请求处理时间。但是,它会增加服务器的吞吐量,通过将初始请求处理线程释放回I/O容器中,而请求可能仍在队列中等待处理,或者处理可能仍在另一个专用线程上运行。O容器线程可用于接受和处理新传入的请求连接。

tp5buhyn

tp5buhyn1#

@暂停有更明确的如果你使用它,否则它不会有任何区别使用它。
让我们来谈谈它的好处:

  • @Suspended会暂停/挂起当前线程直到它得到响应,默认情况下#NO_TIMEOUT没有挂起超时设置.所以这并不意味着你的请求响应(I/O)线程会得到空闲并可用于其他请求.
  • 现在假设你想让你的服务在某个特定的时间内响应,但是你从资源调用的方法不能保证响应时间,那么你将如何管理你的服务响应时间呢?那时,你可以使用@Suspended为你的服务设置挂起超时,甚至在超过时间时提供回退响应。

下面是设置挂起/暂停超时的一些代码示例

public void longRunningOperation(@Suspended AsyncResponse ar) {
       ar.setTimeoutHandler(customHandler);
       ar.setTimeout(10, TimeUnit.SECONDS);
       final String result = executeLongRunningOperation();
       ar.resume(result);
}

有关详细信息,请参阅

vshtjzan

vshtjzan2#

@Suspended注解添加在resource方法上的AsyncResponse参数之前,以告知基础Web服务器不期望此线程为远程调用者返回响应:

@POST
public void asyncPost(@Suspended final AsyncResponse ar, ... <args>) {
    someAsyncMethodInYourServer(<args>, new AsyncMethodCallback() {
        @Override
        void completed(<results>) {
            ar.complete(Response.ok(<results>).build());
        }

        @Override
        void failed(Throwable t) {
            ar.failed(t);
        }
    }
}

相反,AsyncResponse对象由在回调对象上调用completed或failed的线程使用,以向客户端返回“ok”或引发错误。
考虑将此类异步资源与async jersey客户端结合使用。如果您尝试实现一个公开基本异步API的ReST服务,这些模式允许您通过ReST接口投射异步API。
我们不创建异步接口,因为我们有一个需要很长时间的过程(几分钟或几小时),而是因为我们不希望线程一直处于休眠状态-我们发送请求并注册回调处理程序,以便在结果准备就绪时(从几毫秒到几秒后)调用它-在同步接口中,调用线程将在此期间处于休眠状态,而不是做一些有用的事情。有史以来最快的Web服务器之一是单线程的,完全异步的。这个线程从不休眠,因为只有一个线程,所以没有上下文切换(至少在这个进程内)。

ugmeyewa

ugmeyewa3#

@suspend注解让调用者实际上等待你的工作完成。假设你在另一个线程上有很多工作要做。当你使用jersey @suspend时,调用者只是坐在那里等待(所以在web浏览器上他们只看到一个微调器),直到你的AsyncResponse对象向它返回数据。
假设您有一个非常长的操作要做,并且您想在另一个线程(或多个线程)上完成它。现在我们可以让用户等待,直到我们完成。不要忘记在jersey中,您需要在web.xml的jersey servlet定义中添加“true”来让它工作。

相关问题