Chris
Chris

Reputation: 27384

PHP: Detect and show "Server overloaded" message

I have noticed a few websites such as hypem.com show a "You didnt get served" error message when the site is busy rather than just letting people wait, time out or refresh; aggravating what is probably a server load issue.

We are too loaded to process your request. Please click "back" in your browser and try what you were doing again.

How is this achieved before the server becomes overloaded? It sounds like a really neat way to manage user expectation if a site happens to get overloaded whilst also giving the site time to recover.

Upvotes: 3

Views: 6077

Answers (6)

Pierre
Pierre

Reputation: 1583

Another options is this:

$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.');
}

I got it from php's site http://php.net/sys_getloadavg, altough I'm not sure what the values represent that the sys_getloadavg returns

Upvotes: 3

Pierre
Pierre

Reputation: 1583

You can use the php tick function to detect when a server isn't loading for a specified amount of time, then display an error messages. Basic usage:

<?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 ; 
}

The while(true) is just to simulate a loaded server. To implement the script in your site, you need to remove the while statement and add your page logic E.G dispatch event or front controller action etc.

And the $connectionWaitingTime in the checkCOnnection function is set to timeout after 3 seconds, but you can change that to whatever you want

Upvotes: 1

AD7six
AD7six

Reputation: 66198

You could simply create a 500.html file and have your webserver use that whenever a 50x error is thrown.

I.e. in your apache config:

ErrorDocument 500 /errors/500.html

Or use a php shutdown function to check if the request timeout (which defaults to 30s) has been reached and if so - redirect/render something static (so that rendering the error itself cannot cause problems).

Note that most sites where you'll see a "This site is taking too long to respond" message are effectively generating that message with javascript.

Upvotes: 2

julien_c
julien_c

Reputation: 5092

This is not a strictly PHP solution, but you could do like Twitter, i.e.:

  • serve a mostly static HTML and Javascript app from a CDN or another server of yours
  • the calls to the actual heavy work server-side (PHP in your case) functions/APIs are actually done in AJAX from one of your static JS files
  • so you can set a timeout on your AJAX calls and return a "Seems like loading tweets may take longer than expected"-like notice.

Upvotes: 1

Akhil Thayyil
Akhil Thayyil

Reputation: 9403

You can restrict the maximum connection in apache configuration too...

Refer

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients

http://www.howtoforge.com/configuring_apache_for_maximum_performance

Upvotes: 1

Matt Gibson
Matt Gibson

Reputation: 14949

This may be to do with the database connection timing out, but that assumes that your server has a bigger DB load than CPU load when times get tough. If this is the case, you can make your DB connector show the message if no connection happens for 1 second.

You could also use a quick query to the logs table to find out how many hits/second there are and automatically not respond to any more after a certain point in order to preserve QOS for the others. In this case, you would have to set that level manually, based on server logs. An alternative method can be seen here in the Drupal throttle module.

Another alternative would be to use the Apache status page to get information on how many child processes are free and to throttle id there are none left as per @giltotherescue's answer to this question.

Upvotes: 1

Related Questions