The first step is to download, build and install HAProxy. We highly recommend version 1.3.15.4 or later.
wget http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.15.tar.gz
tar xvzf haproxy*
cd haproxy*
make TARGET=linux26
cp haproxy /usr/
sudo install –owner=root –group=root -m700 haproxy /usr/sbin/
Configuring the proxy server
Copy the following configuration file.
global
# maximum number of simultaneous active connections from an upstream web server
maxconn 500
# Logging to syslog facility local0
# log 127.0.0.1 local0
# Distribute the health checks with a bit of randomness
spread-checks 5
# Uncomment the statement below to turn on verbose logging
#debug
# Settings in the defaults section apply to all services (unless you change it,
# this configuration defines one service, called rails).
defaults
# apply log settings from the global section above to services
log global
# Proxy incoming traffic as HTTP requests
mode http
# Distribute incoming requests between Mongrels by round robin algorythm.
# Note that because of ‘maxconn 1′ settings in the listen section, Mongrels
# that are busy processing some other request will actually be skipped.
# So, the actual load-balancing behavior is smarter than simple round robin.
balance roundrobin
# Maximum number of simultaneous active connections from an upstream web server
# per service
maxconn 500
# Log details about HTTP requests
option httplog
# Abort request if client closes its output channel while waiting for the
# request. HAProxy documentation has a long explanation for this option.
option abortonclose
# Check if a “Connection: close” header is already set in each direction,
# and will add one if missing.
option httpclose
# If sending a request to one Mongrel fails, try to send it to another, 3 times
# before aborting the request
retries 3
# Do not enforce session affinity (i.e., an HTTP session can be served by
# any Mongrel, not just the one that started the session
option redispatch
# Timeout a request if the client did not read any data for 120 seconds
timeout client 120000
# Timeout a request if Mongrel does not accept a connection for 120 seconds
timeout connect 120000
# Timeout a request if Mongrel does not accept the data on the connection,
# or does not send a response back in 120 seconds
timeout server 120000
# Remove the server from the farm gracefully if the health check URI returns
# a 404. This is useful for rolling restarts.
http-check disable-on-404
# Enable the statistics page
stats enable
stats uri /haproxy?stats
stats realm Haproxy\ Statistics
stats auth haproxy:stats
# Create a monitorable URI which returns a 200 if haproxy is up
monitor-uri /haproxy?monitor
# Specify the HTTP method and URI to check to ensure the server is alive.
# see http://github.com/jnewland/pulse
#option httpchk GET /pulse
# Amount of time after which a health check is considered to have timed out
timeout check 2000
# Rails service section.
listen Servers :80
server Server-1 localhost:8001 maxconn 1 check inter 20000 fastinter 1000 fall 1
At the bottom of the file, edit the listen section to use the correct mongrel ports. If you have more than one application, you can add additional listen blocks. For each additional listen block, increment the haproxy listen port (9000,9001,9002,etc) and adjust the mongrel ports for the application (8000, 8010, 8020,etc).
Save the configuration to your server as /etc/haproxy.conf.
Now save the following script to /etc/init.d/haproxy, then run:
#!/bin/sh
#
# chkconfig: – 85 15
# description: HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited \
# for high availability environments.
# processname: haproxy
# config: /etc/haproxy.conf
# pidfile: /var/run/haproxy.pid
# Script Author: Simon Matter <simon.matter@invoca.ch>
# Version: 2004060600
# Source function library.
if [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
. /etc/rc.d/init.d/functions
else
exit 0
fi
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
# This is our service name
BASENAME=`basename $0`
if [ -L $0 ]; then
BASENAME=`find $0 -name $BASENAME -printf %l`
BASENAME=`basename $BASENAME`
fi
[ -f /etc/$BASENAME.conf ] || exit 1
RETVAL=0
start() {
/usr/sbin/$BASENAME -c -q -f /etc/$BASENAME.conf
if [ $? -ne 0 ]; then
echo “Errors found in configuration file, check it with ‘$BASENAME check’.”
return 1
fi
echo -n “Starting $BASENAME: ”
daemon /usr/sbin/$BASENAME -D -f /etc/$BASENAME.conf -p /var/run/$BASENAME.pid
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$BASENAME
return $RETVAL
}
stop() {
echo -n “Shutting down $BASENAME: ”
killproc $BASENAME -USR1
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$BASENAME
[ $RETVAL -eq 0 ] && rm -f /var/run/$BASENAME.pid
return $RETVAL
}
restart() {
/usr/sbin/$BASENAME -c -q -f /etc/$BASENAME.conf
if [ $? -ne 0 ]; then
echo “Errors found in configuration file, check it with ‘$BASENAME check’.”
return 1
fi
stop
start
}
check() {
/usr/sbin/$BASENAME -c -q -V -f /etc/$BASENAME.conf
}
rhstatus() {
status $BASENAME
}
condrestart() {
[ -e /var/lock/subsys/$BASENAME ] && restart || :
}
# See how we were called.
case “$1″ in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
restart
;;
condrestart)
condrestart
;;
status)
rhstatus
;;
check)
check
;;
*)
echo $”Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}”
RETVAL=1
esac
exit $RETVAL
sudo chmod +x /etc/init.d/haproxy
sudo chkconfig haproxy on
sudo /sbin/service haproxy start
Test your configuration before you continue (you might need to ‘yum install -y curl’):
curl localhost:9000
You should see the HTML from the root URL of your application. If not, double check your settings and restart the proxy with sudo /sbin/service haproxy restart until you do.
Configuring Apache
Once things seem to be working, you can update your Apache configuration. This will be located on your server at /etc/httpd/conf/apps/APPNAME.conf. If you configured the application as the default vhost, then it will be at /etc/httpd/conf/default.conf
Be sure to backup your configuration just in case, and then:
- Remove the mod_proxy_balancer that start with: <Proxy balancer://APPNAME_cluster>
- Look for this line: RewriteRule ^/(.*)$ balancer://APPNAME_cluster%{REQUEST_URI} [P,QSA,L]
- And change it to this: RewriteRule ^/(.*)$ http://localhost:7001%{REQUEST_URI} [P,QSA,L]
Be sure to use the correct listen port for your application. In the haproxy configuration template, we use 8001 for the first application.
Restart Apache to reload the configuration.
sudo /sbin/service httpd restart
Proxy Statistics
HAProxy provides a status page showing the health of your mongrels. To see your status page, visit http://yourapp.com/haproxy?stats. The username/password for the stats page are haproxy/stats in our configuration template – feel free to tweak this to your liking.
Health Checks
In the provided configuration template, HAProxy will attempt to load the home page of your application from each mongrel once every twenty seconds to verify that each mongrel is available for new requests. If your home page is cached or doesn’t perform very well, you may perfer to install pulse. Pulse is a Rails plugin that provides a lightweight action intended soley for health checks. Once you install pulse, uncomment the following line in your HAProxy config:
option httpchk GET /pulse
Restart HAProxy to reload the configuration.
sudo /sbin/service haproxy restart