codenode
10-04-2004, 04:12 AM
In my line of work I see a lot of servers that like to run 50 to
thousands of websites on a single server, the lot of which want
MySQL, PHP, etc. to all run as if they were the only website
accepting connections. Somehow owners of such servers don't
believe me when I say: The server is maxed out, if we increase
Apache's limits it will only make things worse. Aside from watching
vmstat I found myself always looking to see how many Apache
processes were running, what MaxClients was set to, and how
many established web connections there currently were. Then
I did the smart (or lazy) thing and made a Perl script to do it
for me: apacheload.pl
It makes a little report like this:
Apache MaxClients: 250
Apache processes: 221
Established web connections: 191
Apache load: 77%
There's a little more to read about it (like what happens when
Apache load exceeds 100%) at:
<link removed>
Or you can simply grab it with:
wget codenode.com/apacheload.pl
I'd like to hear what others can get on Apache performance index
while still keeping their whole server running smoothly.
sprintserve
10-04-2004, 06:52 AM
I will post the code here since I removed the link...
#!/usr/bin/perl
# apacheload.pl version 1
use POSIX ceil;
# Get and print MaxClients value from httpd.conf
$httpd_conf = '/etc/httpd/conf/httpd.conf';
$mc = `grep MaxClients ${httpd_conf} 2>&1`;
(undef,$mc) = split(/\s/, $mc);
print "Apache MaxClients: $mc\n";
# Get and print number of running child httpd processes or
# print message if Apache is not running
$a_procs = `ps ax | grep httpd -c 2>&1`;
$a_procs -= 3;
if($a_procs > 0) { print "Apache processes: $a_procs\n"; }
else { print "Apache is not running\n"; };
# Get and print number of established port 80 and 443 Internet connections
$est_conns = `netstat -nA inet | grep :80 | grep -c EST`;
$est_conns += `netstat -nA inet | grep :443 | grep -c EST`;
print "Established web connections: $est_conns\n";
# Calculate and print Apache load or print nothing if Apache is not running.
if($a_procs > 0)
{
$al = ceil(($est_conns * 100) / $mc);
print "Apache load: ${al}%\n";
if($est_conns > $mc)
{
$alratio = $est_conns / $mc;
printf("Apache performance index: %.5s\n", $alratio);
}
}
Lem0nHead
10-04-2004, 02:40 PM
it maybe a better idea to get this info from mod_status
codenode
10-04-2004, 08:30 PM
I'm prone to agree. Thank you for the input.
LoganNZ
10-05-2004, 04:27 AM
Nice idea.
Good work :)
I wouldn't call it lazy, i would call it smart/intelligent :D
codenode
10-14-2004, 01:16 PM
Thx to Lem0nHead I re-evaluated the script. I think "load" was a wrong descriptor because mod_status does show real load better. However it does have its own limitations, mainly that it's disabled by default, might have an ACL, and only shows the connections being served. Since I work on different servers every day I can't enable the server-status directive, set the ACL, and graceful restart Apache on every one. So I updated the script: It's apachecc.pl (connection capacity) and it works w/ Apache 2.0 prefork MPM where there may be multiple MaxClients values. Next on the list is grouping common IPs from netstat so you can see if one IP is making hundreds of connections itself.
Here's the script since posting links to my non-commercial website is still in dispute ;)
#!/usr/bin/perl
# codenode.com/apachecc.php apachecc.pl 10122004
use POSIX ceil;
# Get and print the first MaxClients value from httpd.conf
$httpd_conf = '/etc/httpd/conf/httpd.conf';
$mc = `grep -m 1 -P ^MaxClients ${httpd_conf} 2>&1`;
(undef,$mc) = split(/\s+/, $mc);
print "Apache MaxClients: $mc\n";
# Get and print number of running child httpd processes or
# print message if Apache is not running
$a_procs = `ps ax | grep httpd -c 2>&1`;
$a_procs -= 3;
if($a_procs > 0) { print "Apache processes: $a_procs\n"; }
else { print "Apache is not running\n"; };
# Get and print number of established port 80 and 443 Internet connections
$est_conns = `netstat -nA inet | grep :80 | grep -c EST`;
$est_conns += `netstat -nA inet | grep :443 | grep -c EST`;
print "Established web connections: $est_conns\n";
# Calculate and print Apache cc or print nothing if Apache is not running.
if($a_procs > 0)
{
$al = ceil(($est_conns * 100) / $mc);
print "Apache cc: ${al}%\n";
}
andreyka
10-14-2004, 02:27 PM
I made little bit changes for this script work in FreeBSD:
#!/usr/bin/perl
# codenode.com/apachecc.php apachecc.pl 10122004
use POSIX ceil;
# Get and print the first MaxClients value from httpd.conf
$httpd_conf = '/etc/httpd/conf/httpd.conf';
$mc = `grep ^MaxClients ${httpd_conf} | awk '{ print $2 }' 2>&1`;
(undef,$mc) = split(/\s+/, $mc);
print "Apache MaxClients: $mc\n";
# Get and print number of running child httpd processes or
# print message if Apache is not running
$a_procs = `ps ax | grep httpd -c 2>&1`;
$a_procs -= 3;
if($a_procs > 0) { print "Apache processes: $a_procs\n"; }
else { print "Apache is not running\n"; };
# Get and print number of established port 80 and 443 Internet connections
$est_conns = `sockstat -4 -c | grep -c httpd`;
print "Established web connections: $est_conns\n";
# Calculate and print Apache cc or print nothing if Apache is not running.
if($a_procs > 0)
{
$al = ceil(($est_conns * 100) / $mc);
print "Apache cc: ${al}%\n";
}