8

我有一个 Web 应用程序,它充当运行很长任务的异地服务器的接口。用户输入信息并点击提交,然后 chrome 等待响应,并在收到它时加载一个新网页。然而,根据网络、用户的输入,该任务可能需要相当长的时间,并且有时 chrome 会在返回数据之前加载“未收到数据页面”(尽管任务仍在运行)。

有没有办法在我的任务正在思考时放置一个临时页面,或者只是强制 chrome 继续等待?提前致谢

4

3 回答 3

15

虽然您可以更改服务器上的超时或其他技巧以尝试保持页面“活动”,但请记住,您无法控制的连接的其他部分可能会使请求超时(例如超时浏览器的值,或浏览器和服务器之间的任何代理等)。此外,如果任务需要更长的时间才能完成(变得更高级,或者因为更多人使用它而变得更慢),您可能需要不断提高超时值。

最后,这类问题通常通过改变架构来解决。

对长时间运行的任务使用单独的进程

视图不是在处理视图中提交请求并运行任务,而是在单独的进程中开始运行任务,然后立即返回响应。此响应可以将用户带到“请稍候,我们正在处理”页面。该页面可以使用许多推送技术中的一种来确定任务何时完成(长轮询、Web 套接字、服务器发送事件、每 N 秒一次 AJAX 请求,或者最简单的方法:重新加载页面每 5 秒)。

让您的 Web 请求“启动”单独的流程

无论如何,正如我所说,处理请求的视图不会执行长时间的操作:它只是启动一个后台进程来为其完成任务。你可以自己创建这个后台进程调度(查看这个 Flask 片段以获得可能的想法),或者使用像Celery或(RQ)这样的库。

任务完成后,您需要某种方式通知用户。这将取决于您在上面选择的通知方法。对于一个简单的“每 N 秒 ajax 请求”,您需要创建一个视图来处理检查任务是否完成的 AJAX 请求。执行此操作的典型方法是让长时间运行的任务作为最后一步对数据库进行一些更新。然后,检查状态的请求可以检查数据库的这一部分是否有更新。

的优点和缺点

使用这种方法(而不是试图将长时间运行的任务放入请求中)有一些好处:

1.) 处理长时间运行的 Web 请求是一项棘手的工作,因为有多个可能超时的点(除了浏览器和服务器)。使用这种方法,您的所有 Web 请求都非常短,并且不太可能超时。

2.) Flask(和其他类似的框架)被设计成只支持一定数量的可以响应网络查询的线程。假设它有 8 个线程:如果其中四个正在处理长请求,那么只剩下四个请求来实际处理更典型的请求(比如用户获取他们的个人资料页面)。一半的 Web 服务器可能会忙于做一些不提供 Web 内容的事情!更糟糕的是,您可能让所有八个线程都运行一个长进程,这意味着您的站点完全无法响应 Web 请求,直到其中一个线程完成。

主要缺点:在启动和运行任务队列方面需要做更多的设置工作,而且它确实会使您的整个系统稍微复杂一些。但是,我强烈推荐这种策略用于在 Web 上运行的长时间运行的任务。

于 2013-08-08T15:54:38.887 回答
0

我相信这是由于您的 Web 服务器(大多数情况下是 apache)的超时时间太小。尝试增加这个数字

对于 apache,看看timeout 选项

编辑:我不认为你可以在 Chrome 中设置这个时间(即使它真的很旧,也可以在谷歌论坛上看到这个主题)在 Firefox 中,在 about:config 页面上,输入timeout,你会有一些可以设置的选项. 我不知道 Internet Explorer。

于 2013-08-08T13:41:57.237 回答
0

让我们假设:

  1. 这不是服务器问题,所以我们不必摆弄 Apache、nginx 等超时设置。

  2. 延迟是几分钟,而不是几小时或几天,只是为了使场景易于管理。

  3. 您控制用户点击提交的网页,以及管理用户交互的网页。

如果获得了这些,我建议不要使用标准的 HTML 表单提交,而是让提交按钮启动一个 JavaScript 函数来监督处理。它会发出“请耐心等待...这可能需要一点时间”样式的消息,然后使用 jQuery.ajax 来调用具有较长超时值的长时间占用服务器。jQuery 超时以毫秒为单位,因此 60000 = 60 秒。如果它比这更长,请相应地增加您指定的超时时间。我看到报告称并非所有客户端都允许超长超时(例如,iOS 上的 Safari 显然有 60 秒的限制)。但总的来说,这将为您提供一个平台来管理交互(与您的用户,与慢速服务器),而不是受制于简单的 Web 表单提交。

这里有一些边缘情况需要考虑。Web 服务器超时可能确实需要向上调整(Apache 默认为 300 秒,即 5 分钟,而 nginx 更少,IIRC)。您的客户端超时(例如在 iOS 上)对于您所看到的延迟而言,最大值可能太低了。等等。这些情况需要在服务器上进行调整,或者采用不同的交互策略。但是 AJAX 管理的交互是我要开始的地方。

于 2013-08-08T15:40:57.557 回答