Show a “We are Busy” page when your server is too busy by using PHP

If you are apache fan. You shold have many virtual host in your apache conf. But after your site getting popular, sometimes your server can not handle all request and your visitor will have to wait in front of the browser.

I could not find a nice solution for that so created one.

First, create a html page that will be shown when your server is busy.

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">
  #main  { background-color: #fcc; }
</style>
<title>We are busy</title>
</head>
 
<body>
<div id="main">
<p>
Many visitors are accessing my server or I'm encoding some movies on the server.
</p>
<p>
Wait just a few second and <a ref="javascript:location.reload()">reload</a>.
</p>
</div>
</body>
</html>

Save above file as “/phpGlobal/busy.html”. The directory can be anywhere as you like.

Next, create a php that check whether my server is heavy.

<?php
checkMachineState();
function checkMachineState()
{
        $a = @file_get_contents('/proc/loadavg');
        if(!$a) {
                return;
        }
        $a = explode(' ',$a);
 
        if($a[0] <= 3)
        // if(false)
        {
                return;
        }
        header ('HTTP/1.0 503 Service Temporarily Unavailable');
        require 'busy.html';
        exit();
}
?>

Save above as “/phpGlobal/check.php”
This will show “busy.html” when the load avarage exceeds 3.

Next, add this line on apache2.conf or your conf file.

php_value auto_prepend_file /phpGlobal/check.php

NOw when you restarts apache2. “check.php” will run before any php requests.

check.php uses UTF-8 that will disturb with your character code of your environment.
In that case, try to consider adding these lines to check.php.

@ini_set ( 'default_charset' , '');
header ('Content-Type: text/html; charset=UTF-8');

At last, you can see a current load average by using “top” command. At top right corner of the command output.

phpMyAdmin says “Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly.”

You need to create “tmp” directory where php saves session data. In windows its location is typically same folder as php.exe resides. Open phpinfo() and look for “session.save_path” for the actual path.

busyrebooter

I wanted to reboot my ubuntu server when it got very busy state. After trying monit which I think this software has such function, I realize this is a monitoring tool and does not have a such function. That why I created very simple app ‘busyrebooter’.

/proc/loadavg shows the busy state.

$ cat /proc/loadavg
0.36 0.25 0.25 1/182 7658
$

In fact, this proc file is used by tools such as uptime or top. The first 3 columns show the load average of 1, 5, and 15 minutes. Checking 2nd column to see the system is busy or not, and if it was busy, reboot the system. I wrote a C code.

#include <stdio.h>
#include <unistd.h>
 
int main(int argc, char* argv[])
{
	float avr = 0;
	float tmp = 0;
	int fret;
 
	FILE* f = fopen("/proc/loadavg", "r");
	fret = fscanf(f, "%f %f",&tmp, &avr);
	if(fret != 2) {
		perror("fscanf unmatched");
	}
	fclose(f);
 
	if(avr > 20)
	{
		char command[] = "/sbin/reboot";
		char    *exargv[] = {"/sbin/reboot", NULL};
		char    *exenvp[] = {NULL};
		execve(command, exargv, exenvp);
		perror("Could not execute command");
	}
 
	return 0;
}

Compiling.

$ gcc -o busyrebooter main.c

This program executes /sbin/reboot which needs the root privilege.

Add an entry to /etc/crontab to run this program by every 10 minutes.

*/10 *  * * *   root    [ -x /root/bin/busyrebooter ] && /root/bin/busyrebooter