有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在完成繁重的服务器计算时在客户端上继续

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

我有:

  • OldApp—从命令行启动的Java应用程序(此处没有web前端)
  • NewApp—一个Java应用程序,在Apache后面有一个RESTAPI

我希望OldApp通过restapi调用NewApp,当NewApp完成后,OldApp应该继续

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

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

像这样的东西有什么好的设计模式吗?我把事情复杂化了吗?关于如何思考有什么建议吗


共 (3) 个答案

  1. # 1 楼答案

    如果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",
        ...
    }
    
  2. # 2 楼答案

    问题是关于java和Servlet。。。所以我建议大家看看Servlet 3.0异步支持

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

    在服务器上分叉的线程需要实现可调用接口。我还建议为此使用线程池。分叉作业的GET url可以检查未来的对象状态,并将其返回给用户

  3. # 3 楼答案

    是的,这正是人们现在对休息所做的。因为无法从服务器连接到客户机,所以客户机只是经常轮询。还有一些改进的方法称为“长轮询”,当客户端和服务器之间的连接有较大超时时,服务器会在连接的客户端可用时将信息发送回连接的客户端