【问题标题】:Can 1330316 AJAX requests crash my server?1330316 AJAX 请求会导致我的服务器崩溃吗?
【发布时间】:2011-01-16 19:30:33
【问题描述】:

我正在构建一个小型 PHP/Javascript 应用程序,它将为美国所有州的所有城市进行一些处理。这会四舍五入到 (52 x 25583) = 1330316 个或更少需要处理的项目。

处理每个项目大约需要 2-3 秒,因此用户可能不得不盯着这个页面 1-2 小时(或者至少在他做其他事情时保持最小化)。

为了给用户最大的反馈,我想通过javascript控制页面的处理,基本上是这样的:

var current = 1;
var max = userItems.length; // 1330316 or less

process();

function process()
{
  if (current >= max)
  {
     alert('done');
     return;
  }

  $.post("http://example.com/process", {id: current}, function()
     {
        $("#current").html(current);
        current ++;
        process();
     }
  );
}

在 html 中,我将收到以下状态消息,每当调用 process() 函数时,该消息就会更新:

<div id="progress">
   Please wait while items are processed.
   <span id="current">0</span> / <span id="max">1330316</span> items have been processed.
</div>

希望你们都能看到我希望它如何工作。

我唯一担心的是,如果同时向服务器发出这 1330316 个请求,是否有可能导致服务器崩溃/关闭?如果是这样,如果我在服务器端 PHP 代码中使用 sleep(3); 为每个请求额外等待 2 秒,这会让事情变得更好吗?

或者是否有一种不同的机制可以向用户显示快速反馈,例如轮询,而不需要我弄乱 apache 或服务器?

【问题讨论】:

  • 每(10,100)个请求更新状态,而不是每个单独的更新呢?这能改善情况吗?
  • 它可以但是我会向用户展示什么?
  • 此代码尚未生效,我只是在实施此代码之前检查它的任何潜在缺点
  • 由于堆栈嵌套太深,您的代码可能在处理过程中的某个时间抛出异常。尽量不要从闭包中运行“进程”函数,而是使用 setTimeout() 在 0 秒后运行它。
  • 这听起来确实需要一个更好的解决方案。为什么不进行迭代服务器端,并让该机制将定期状态更新发布到数据库表? UI 然后可以轮询该表以获取更新状态。在服务器上完成这一切而不是在每次迭代之间放置一个 HTTP 事务会大大降低成本!!

标签: php javascript jquery ajax codeigniter


【解决方案1】:

如果您可以在服务器中放置一个 cronjob,我相信它会工作得更好。使用 cronjob 进行实际处理并使用 Javascript 定期更新状态(例如,每 10 秒)怎么样?

然后,第一步是触发 cronjob PHP 将检查的一些标志。如果它处于活动状态,则必须执行任务(您可以使用一些临时文件来告诉脚本必须处理哪些记录)。

cronjob 会执行任务,然后在其迭代完成时关闭标志。

这样,用户甚至可以关闭您的应用程序并稍后再检查,服务器将处理所有处理,不受客户端活动的干扰。

【讨论】:

  • 不使用 crontab 方式(这并不总是可行)我建议让 php 处理在 3-5 秒内完成尽可能多的批处理,然后返回到 javascript 如何已经做了很多处理和新的索引。然而,这并不能替代真正的后台处理,因为浏览器必须保持打开状态。但它也消除了服务器的负载。
  • cronjob 必须每秒运行一次,不是吗?
  • cronjob 将充当工作进程的调度程序。 “每一秒”意味着它会在一秒的时间分辨率内对新工作做出反应。我不会把它写得那么短,因为它没有意义。
【解决方案2】:

在您的服务器端 php 脚本中设置休眠只会让情况变得更糟。它会导致更多的进程停留,从而增加并行工作/睡眠进程的数量,从而增加内存使用量。

不要担心可以并行完成这么多流程。通常一个 apache 服务器被配置为并行处理不超过 150 个请求。配置良好的服务器不会并行处理比可用资源更多的请求(优秀的管理员会事先进行一些计算)。其他请求必须等待 - 考虑到您的请求计数,它们可能会在处理之前超时。

但是,您应该关注客户端资源,但看起来您的脚本仅在前一个返回时才启动新请求。顺便说一句:行为良好的 HTTP 客户端(您的浏览器应该是)向同一个 IP 并行启动不超过 6 个请求。

更新:除了上述之外,您还应该认真考虑重新设计您的批量处理方法(类似于@Joel 建议的)-但这应该是另一个问题。

【讨论】:

  • 我已决定采用 Cron 工作方式,但感谢您的回复 :)
猜你喜欢
  • 2016-03-02
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多