Apache Cluster Config Sync

January 11, 2010

It has become quite commonplace today, for high traffic sites to require more than one web server.
Here is a small script in charge of synchronizing the server configuration files (/etc/httpd in this example).

In this case, I will be using apache as the web server of choice, simply because of its prevalence and popularity, however the idea is the same, and the script could probably be easily edited to fit your web server of choice (nginx, lighttpd or what have you).

This script was designed with a certain topology in mind: Two (or more) apache servers behind a load balancer.
They must be identical in every way, and that is what the script here comes to assure.
The main issue with this condition is that the servers must listen on * (for instance *:80 or *:443).
That is – they cannot listen on specific IPs, because then the changes to the main server will be replicated across all the servers, causing major disasters. The main case where this will be relevant is when you have more than one secure site (as each SSL requires a dedicated IP).

There is a nice solution to this, involving creating an nginx reverse proxy with name-based ssl virtual hosts relaying traffic to apache virtual hosts separated by ports according to the domain name, however this is (way) out of the scope of this post.

On to the script!

apachesync.sh

#!/usr/bin/env bash

#########################################
###                                   ###
### sync apache config across servers ###
###                                   ###
#########################################

### set master server IP

master_server="123.123.123.123"


### set logging facility \
### (don't forget to edit syslog.conf - see README)

loggy="logger -p local6.notice"


### core of the whole program is the rsync command

syncexec=$(rsync -ai --delete --force ${master_server}:/etc/httpd/ /etc/httpd)


### if nothing to do, rsync returns nothing, \
### in which case $changes should equal 0

changes=$(echo -ne "$syncexec" | wc -l)


### do the actual work - if there are changes, \
### they have already been copied, just reload apache accordingly

if [[ $changes > 0 ]]; then
    $loggy "found changes to sync and reloading apache"
    ### pipe output of $syncexec to stdin of logger, \
    ### and tag as 'rsync' for easier understanding of log
    echo -ne "$syncexec" | $loggy -t rsync
    /etc/init.d/httpd reload
#else
    ### for debugging
    # $loggy "nothing to do"
fi

The code itself is very annotated as you can see, so I won’t go over every part – as it quite simple anyway.

I would say that the cool trick is mainly the -i flag for rsync which means --itemize-changes.
This allows us to check if rsync made changes and if so log them, and restart apache.

Another thing I used here for the first time, is the logger command, which is a very nice utility for sending messages from the command line or from scripts to the syslog logging facility of your choice.
It even has the ability to tag each entry to the log (like I do here for rsync in order to differentiate the scripts output from rsync’s).

Here is the script above for your convenience along with a short README for setting the syslog.conf properly.

Also, in case it wasn’t clear – the recommended implementation of this script is via a cron job, probably every 5 minutes or so should suffice.

That’s it for now.

Have Fun!

tags: , , ,
posted in scripts by tom

Follow comments via the RSS Feed | Leave a comment | Trackback URL

1 Comment to "Apache Cluster Config Sync"

  1. Aravind wrote:

    Can u please post Ubuntu equivalent ?

Leave Your Comment

 
Powered by Wordpress. Theme by Shlomi Noach, openark.org
Hosted by Evolution On-line