【问题标题】:PHP: Detect and show "Server overloaded" messagePHP:检测并显示“服务器过载”消息
【发布时间】:2026-02-17 13:45:01
【问题描述】:

我注意到一些网站,例如hypem.com,在网站繁忙时会显示“您没有得到服务”的错误消息,而不是让人们等待、超时或刷新;加剧了可能是服务器负载问题。

我们负载过重,无法处理您的请求。请点击您的“返回” 浏览器并再次尝试您正在执行的操作。

这是如何在服务器过载之前实现的?如果网站碰巧超载,同时也给网站时间恢复,这听起来是一种非常巧妙的方法来管理用户期望。

【问题讨论】:

    标签: php apache optimization lamp


    【解决方案1】:

    另一个选项是这样的:

    $load = sys_getloadavg();
    if ($load[0] > 80) {
        header('HTTP/1.1 503 Too busy, try again later');
        die('Server too busy. Please try again later.');
    }
    

    我从 php 的网站 http://php.net/sys_getloadavg 得到它,尽管我不确定 sys_getloadavg 返回的值代表什么

    【讨论】:

      【解决方案2】:

      您可以简单地创建一个 500.html 文件,并让您的网络服务器在抛出 50x 错误时使用它。

      即在你的 apache 配置中:

      ErrorDocument 500 /errors/500.html
      

      或使用php shutdown function 检查是否已达到请求超时(默认为 30 秒),如果已达到 - 重定向/呈现静态内容(以便呈现错误本身不会导致问题)。

      请注意,您会看到“此站点响应时间过长”消息的大多数网站实际上是使用 javascript 生成该消息。

      【讨论】:

        【解决方案3】:

        这可能与数据库连接超时有关,但这是假设您的服务器在时间困难时具有比 CPU 负载更大的数据库负载。如果是这种情况,您可以让您的 DB 连接器在 1 秒内未发生连接时显示该消息。

        您还可以使用对日志表的快速查询来找出每秒有多少次点击,并在某个点之后自动不再响应,以便为其他人保留 QOS。在这种情况下,您必须根据服务器日志手动设置该级别。另一种方法可以在 Drupal 节流模块中看到 here

        另一种选择是使用 Apache 状态页面来获取有关有多少子进程空闲的信息,并根据@giltotherescue 对this question 的回答限制 id 没有剩余。

        【讨论】:

        • 听起来很有趣,马特 - 我如何检测它是否在 N 秒内没有连接到数据库?
        • ini_set('mysql.connect_timeout', 5);然后检查连接器是否为假。
        【解决方案4】:
        【解决方案5】:

        这不是一个严格的 PHP 解决方案,但你可以像 Twitter 那样做,即:

        • 从 CDN 或您的其他服务器提供大部分静态 HTML 和 Javascript 应用程序
        • 对实际繁重的服务器端(在您的情况下为 PHP)函数/API 的调用实际上是在 AJAX 中从您的一个静态 JS 文件中完成的
        • 因此您可以设置AJAX 调用超时并返回类似“加载推文可能需要比预期更长的时间”的通知。

        【讨论】:

        • 我认为转换为 SPA 可能超出范围 - 但仍然是一个很好的建议。
        【解决方案6】:

        您可以使用 php tick 函数来检测服务器何时没有加载指定的时间量,然后显示错误消息。基本用法:

        <?php 
        $connection  = false; 
        function checkConnection( $connectionWaitingTime = 3 ) 
        { 
            // check connection & time 
            global $time,$connection; 
            if( ($t = (time() - $time)) >= $connectionWaitingTime && !$connection){  
                echo ("<p> Server not responding  for <strong>$t</strong> seconds !! </p>"); 
                die("Connection aborted");             
            } 
        } 
        
        register_tick_function("checkConnection"); 
        $time = time(); 
        declare (ticks=1) 
        { 
           require 'yourapp.php' // load your main app logic
            $connection = true ; 
        }
        

        while(true) 只是为了模拟一个加载的服务器。 要在您的站点中实现该脚本,您需要删除 while 语句并添加您的页面逻辑 E.G 调度事件或前端控制器操作等。

        checkCONnection 函数中的 $connectionWaitingTime 设置为 3 秒后超时,但您可以将其更改为您想要的任何值

        【讨论】:

        • 打勾函数?严重地?您想添加负载来检测服务器何时加载?
        • 能否再解释一下这里发生了什么? register_tick_function 在做什么?它实际上会导致网站崩溃吗?
        • 一个tick是一个事件,每N个由解析器在declare块中执行的低级tickable语句发生。 N 的值是在声明块的指令部分中使用 ticks=N 指定的。 register_tick_function — 注册一个函数以在每个刻度上执行。因此,如果服务器上的任何内容执行时间超过 3 秒,它就会显示您的错误消息。 @AD7six register_shutdown_function 比 tick 函数更糟糕,因为用户必须等待默认的 30 秒超时才能显示错误页面
        • @AD7six 500 服务器错误也不起作用,因为有时服务器需要很长时间才能响应,并且永远不会返回 500 服务器错误。
        • @pierre 不要“优化”代码,这样它是为更糟糕的情况而设计的——为快乐的道路设计,但优雅地失败。我不同意你对更糟的定义。如果有的话,必须使用 js(如 @julien_c 所建议的那样)处理一般的连接丢失。