Reply to comment

Automatically Restart Apache when it Freezes

This is a rough watchdog script to restart apache on the local machine when the website gets slow. If a GET to the url fails, or takes longer than 60 seconds, the local web server is restarted.

I started to use this after installing a new version of Apache. The system hadn't been properly tuned, and the side effect was that Apache would be nearly wedged, but the rest of the system was merely slow. This happens when Apache or MySQL are getting wedged, but it's not due to the system overloading with too much traffic. Why does it happen? It's hard to say - it could be a configuration problem, a DOS attack, a hack, or a software error. Regardless, it's more important to keep the system responsive, so the service gets restarted.

This script needs some more logging so it can snapshot different system stats, like system load, memory, network connections, processes, etc. before it's really useful for figuring out why the server is unresponsive.

#! /usr/bin/perl

our $LOGFILE = '/var/log/watchapache.log';
our $URL = 'http://your.url.here/';
our $APACHE_RESTART = '/etc/init.d/apache22 restart';
our $SLEEP = 600;

######################################

require WWW::Mechanize;
require Time::Progress;
require POSIX;

our $mech = WWW::Mechanize->new( onerror => \&failed );
$mech->stack_depth(0);

our $p = new Time::Progress;

sub test_server() {
  $p->restart;
  $mech->get( $URL );
  my $elapsed = $p->elapsed;
  write_log( $mech->status() . " elapsed $elapsed");
  if ($elapsed > 60) {
    restart_apache();
  }
}

sub failed() {
  write_log( "Failed " . $mech->status() );
  if ($mech->status() eq '500') {
    ## assume it's a dead server
    restart_apache();
  }
}

sub restart_apache() {
  write_log("restarting apache");
  system( $APACHE_RESTART );
}

sub write_log($) {
  my $line = shift @_;
  if (-e $LOGFILE) {
    open FH, '>>', $LOGFILE;;
  } else {
    open FH, '>', $LOGFILE;
  }
  print FH POSIX::strftime('%D %T', localtime);
  print FH " $line\n";
  close FH;
}

for(;;) {
  test_server();
  sleep( $SLEEP );
}

Reply

The content of this field is kept private and will not be shown publicly.
  • Lines and paragraphs break automatically.

More information about formatting options

18 + 2 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.