【问题标题】:Synchronous Jersey Rest service that initiates a background task?启动后台任务的同步 Jersey Rest 服务?
【发布时间】:2015-05-25 00:27:40
【问题描述】:

这是我遇到的问题,与设计和实现有关:

我有一个接受 POST 请求的 REST Web 服务。没什么特别的。它目前是同步响应的。

但是,此 Web 服务将启动一个可能需要很长时间的后台进程。

我不希望此服务在 30 分钟后响应。

相反,它应该立即向客户端返回一个 ack 响应,仅此而已(即使在 30 分钟后,也不会再发送任何信息)。

如何使用 Jersey 实现这种行为?

我阅读了https://jersey.java.net/nonav/documentation/2.0/async.html#d0e6914的页面。

虽然读起来很有趣,但我没有找到只发送 ACK 类型的响应(类似于 HTTP 200 代码)的方法。

也许我对异步和我想要实现的行为感到困惑。

我刚刚明白我可以在我的@POST 方法中创建一个新线程来处理后台进程,然后立即返回 ACK 响应。

但是在响应被发送回客户端后,这个新线程是否存在?

你会如何实现这个WS?

我希望你能帮助我澄清这一点。

【问题讨论】:

  • 为什么你的线程不能存活?我只想生成一个新线程,因为该线程的结果与客户端无关。
  • @condit :我尝试了这种方法:效果很好。我们将在第一次迭代中坚持它,但我确信每次调用 WS 时创建一个新线程可能会导致一些问题,对吧?
  • 你不应该直接创建线程。您需要使用Executor 来创建线程池。您可以从一个固定大小的线程池开始,然后根据您的应用程序对其进行调整。
  • 非常感谢您的回复。

标签: asynchronous jersey


【解决方案1】:

我认为您链接的 Jersey 2 异步服务器 API 仍将保持客户端连接,直到处理完成。异步处理实际上是 Jersey 内部的,不会影响客户体验。

如果要返回 ACK,可以使用常规 Jersey 方法,将工作委托给另一个线程,然后立即返回。对于这个用例,我建议使用 HTTP 202。

您可以像在 Jersey 2 示例中那样创建一个线程来执行此操作,并且它将在 Jersey 资源方法调用的执行中继续存在:

@POST
public Response asyncPost(String data) {
    new Thread(...).start();
    return Response.status(Response.Status.ACCEPTED).build();
}

话虽如此,一般不建议在应用服务器中创建线程。

如果您使用的是 EE7,我建议您查看 JSR-236 http://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/package-summary.html

如果您使用的是 EE6,则可以考虑将消息发送到队列以由消息驱动 Bean (MDB) 在后台处理。

【讨论】:

  • 感谢您的回复。我对在 Jersey 中使用异步感到有些困惑。您的回答帮助我理解它完全是泽西岛内部的。昨晚我尝试了一个示例代码,它在 WS Jersey 中启动了一个新线程:它运行良好。但是,您指出不建议在应用服务器中使用线程。我们使用的是 Tomcat 6,而不是完全符合 JEE 的服务器。您还建议使用 MDB 实现:JMS 是可行的解决方案吗?再次感谢您的时间和清晰的解释。我会查看您提供的链接。
  • JMS 可以工作(假设消费线程是池化的),这就是 MDB 构建的基础,但 JMS 也不是 EE Web 配置文件的一部分,因此您可能无法使用它除非您有可用的外部 MQ 产品,否则使用 Tomcat 6。如果你不能升级到 EE,我建议至少使用docs.oracle.com/javase/7/docs/api/java/util/concurrent/…。虽然它仍然会在容器范围之外创建线程,但至少它为您提供了一个框架,用于通过 Futures 对任务进行池和异步句柄。
  • 确实,我的问题也得到了同样的答复。感谢您提供的所有详细信息。祝你有美好的一天。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-08
  • 2019-01-25
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-12
相关资源
最近更新 更多