如何在进行繁重的服务器计算时继续在客户端上运行

时间:2014-06-16 14:57:02

标签: java rest asynchronous

这可能是一个简单的问题,但我现在似乎无法找到一个好的解决方案。

我有:

  • OldApp - 从命令行启动的Java应用程序(此处没有Web前端)
  • NewApp - 一个在Apache背后有RES​​T api的Java应用程序

我希望 OldApp 通过其REST API调用 NewApp ,当 NewApp 完成后, OldApp 应该继续。

我的问题是NewApp正在做很多可能花费很多时间的事情,在某些情况下会导致Apache超时,然后向OldApp发送502错误。计算在NewApp中继续,但OldApp不知道NewApp何时完成。

我想到的一个解决方案是在NewApp中分叉一个线程,并为API请求存储某种ID,并将其返回给OldApp。然后OldApp可以轮询NewApp以查看线程是否已完成,如果是,则继续。否则 - 继续投票。

对于像这样的东西,有没有好的设计模式?我让事情复杂化了吗?关于如何思考的任何提示?

3 个答案:

答案 0 :(得分:3)

如果NewApp花了很长时间,它应立即返回202 Accepted。响应应该包含一个Location标题,指示用户在完成后可以查看结果的位置,以及对请求何时完成的估计。

OldApp应该等到达到估计时间,然后向该位置提交新的GET调用。该GET的响应将是预期数据,或具有新估计时间的实体。然后,OldApp可以在稍后重试,重复直到预期的数据可用。

所以对话可能看起来像:

POST /widgets
response:
202 Accepted
Location: "http://server/v1/widgets/12345"
{
    "estimatedAvailableAt": "<whenever>"
}

GET /widgets/12345
response:
200 OK
Location: "http://server/v1/widgets/12345"
{
    "estimatedAvailableAt": "<wheneverElse>"
}

GET /widgets/12345
response:
200 OK
Location: "http://server/v1/widgets/12345"
{
    "myProperty": "myValue",
    ...
}

答案 1 :(得分:0)

是的,这正是人们现在正在使用REST做的事情。因为没有办法从服务器连接到客户端,客户端只是经常轮询。还有一些名为&#34; long polling&#34;的改进方法,当客户端和服务器之间的连接有大的超时时,服务器在可用时将信息发送回连接的客户端。

答案 2 :(得分:0)

关于java和servlets的问题......所以我建议看一下Servlet 3.0的异步支持。

从设计的角度来看,您需要将带有Id和URL的202返回到作业。 oldApp需要使用URL检查操作的结果。

您在服务器上分叉的线程需要实现Callable接口。我还建议使用线程池。分叉的作业的GET URL可以检查Future对象状态并将其返回给用户。

相关问题