【问题标题】:In a RESTful web service, is it acceptable for the server to take many minutes to respond?在 RESTful Web 服务中,服务器需要几分钟来响应是否可以接受?
【发布时间】:2016-08-21 15:34:52
【问题描述】:

我正在使用 flask-restful 开发一个 RESTful Web 服务。

客户端需要能够请求服务器执行的作业。这项工作可能需要约 1 秒到约 1 小时的时间来执行。一般情况下,预计需要 1-5 分钟。

作业完成后,客户端需要下载 JSON 转储。大小从 100KB 到 100MB 不等。

我看到了 2 个选项:

  1. 客户端以 POST 请求的形式提交作业,只有在作业完成时服务器才会响应。响应包括 JSON 转储。
  2. 客户端将作业作为 POST 请求提交,服务器立即以 200 OK 响应。然后,客户端每隔 60 秒提交一次 GET 状态请求。作业完成后,它会提交另一个 GET 请求以下载 JSON 转储。

根据 REST 原则,哪个选项更受欢迎?

我看到的选项 1 的问题是在等待响应时网络中断的可能性。

【问题讨论】:

  • 想象一下,当您选择选项 1 时,有 10 个客户端在等待响应。现在将其扩展到 100 个客户端、1000 个等。您的服务器将以多快的速度耗尽资源来处理所有这些连接?如果他们不等待工作完成,而是获得一个工作编号进行轮询,他们需要多快?
  • 您应该响应 202,而不是 200:“202(Accepted)状态码表示请求已被接受处理,但处理尚未完成。”然后,此响应可以包含一个有效负载,其中包含估计完成时间、在哪里查找结果等信息。参见例如farazdagi.com/blog/2014/rest-long-running-jobs
  • @MartijnPieters:问得好。这项工作是相当资源(CPU / mem)密集型的。因此,我认为这两种选择的资源都没有很大差异。最多有几千个连接,所以我不希望 Flask 用那个饱和。
  • 请注意,简短的回答是否定的:您的服务器应尽快响应有关正在发生的事情以及客户端下一步应该做什么(如果有的话)的信息。有时这是立即的 200/201,有时(如果您知道这需要一段时间)立即是 202,然后客户端可以发出额外的状态更新请求。
  • 我认为这已经在 SO 的几个地方得到了回答——我错过了什么吗?例如stackoverflow.com/questions/33009721/…stackoverflow.com/questions/16470290/long-running-rest-api.

标签: python rest flask restful-architecture flask-restful


【解决方案1】:

等待几秒钟以上是绝对不行

大多数 Web 基础架构并非旨在处理如此长的延迟,并且一些代理/负载平衡器可能会超时 - 即使您的服务器最终产生响应,也不会有人阅读它。此外,用户会感到无聊并开始刷新/取消/什么的。

正如@jonrsharpe 在评论中提到的那样,您的服务器应尽快响应有关正在发生的事情的信息。输入202 Accepted状态码:

请求已被接受处理,但处理尚未完成。该请求最终可能会或可能不会被执行,因为在实际进行处理时它可能会被禁止。无法从诸如此类的异步操作中重新发送状态代码。

(取自restapitutorial

因此,使用202 和结果应该在哪里的句柄进行响应 - 无论是在正文中还是在响应标头中。然后客户端可以轮询给定位置以查看作业状态并下载结果。

如果结果很大,允许HEAD请求结果也是合理的,这样用户可以轮询HEAD检查结果是否可用,然后用GET下载,不会突然投票期间被淹。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-15
    • 2017-12-24
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    • 2016-12-08
    • 2023-02-14
    • 1970-01-01
    相关资源
    最近更新 更多