Full-service Internet Marketing & Web Development
Recent Posts

Sponsors
![]() |
How to install and configure HAProxy as an HTTP load balancerMichel Nadeau, 03-26-2009 |
HAProxy is a free, very fast and reliable solution offering high availability, load balancing, and proxying for TCP and HTTP-based applications. It is particularly suited for web sites crawling under very high loads while needing persistence or Layer7 processing. Supporting tens of thousands of connections is clearly realistic with todays hardware. Its mode of operation makes its integration into existing architectures very easy and riskless, while still offering the possibility not to expose fragile web servers to the Net.
This post will explain how to install HAProxy on FreeBSD and how to configure it as a simple HTTP load balancer.
1. Getting HAproxy
The first step is to download HAProxy. You can find the latest version at this address:
http://haproxy.1wt.eu/#down
As of writing this post, the latest version is 1.3.16, which you can find here:
http://haproxy.1wt.eu/download/1.3/s...-1.3.16.tar.gz
2. Prepare for installation
Log on your FreeBSD machine and change to the temporary directory of your choice. You can now issue the easy following commands:
HAProxy is now downloaded, unpacked and ready to be compiled.
3. Compile HAProxy
If you are running FreeBSD, you can simply issue the following command:
If you are running another version of Linux, please refer to the README file (included with HAProxy) to find the good way to compile HAProxy on your system.
4. Install HAProxy
Once HAProxy is compiled, you will find a light-weight, standalone "haproxy" executable.
You can copy it where you want, it's your choice! Something like this can be a good choice:
Why? Simply because /usr/local/sbin is usually in $PATH, so haproxy will then be easy to run simply by typing "haproxy".
5. Configuring HAProxy
The configuration of HAProxy, like its installation, is really easy. In fact, it can be very easy, or very complex. HAProxy is VERY flexible and it has literally thousands of parameters you can tweak. You can find the whole documentation on the HAProxy official Web site there:
http://haproxy.1wt.eu/#docs
As of writing this post, the latest official documentation is there:
http://haproxy.1wt.eu/download/1.3/d...figuration.txt
For this post, we'll keep it simple and configure a simple load balancer.
You can put the HAProxy configuration file where you wish, and name it as you wish! This post will be using this path/filename:
And here's our simple configuration file:
global
maxconn 4096
pidfile /var/run/haproxy.pid
daemon
defaults
mode http
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen GALAXY aaa.bbb.ccc.ddd:80
mode http
cookie GALAXY insert
balance roundrobin
option httpclose
option forwardfor
stats enable
stats auth myuser:mypass
server EARTH 192.168.0.2:8080 cookie GALAXY_SERVER_01 check
server MOON 192.168.0.3:8080 cookie GALAXY_SERVER_02 check
> aaa.bbb.ccc.ddd should be the public IP of your server.
> 192.168.0.2 should be the LAN IP to your server 1.
> 192.168.0.3 should be the LAN IP to your server 2.
Everything that is in CAPS is customizable:
Basically, this configuration file is defining a group ("listen" block) called GALAXY, which contains 2 servers: EARTH and MOON. The "roundrobin" balance option is telling to HAProxy to alternate between the 2 servers all the time. For the other options in the global, defaults and listen blocks, they're pretty standard. If you need to tweak those or to add options to suit your needs, I'm sure HAProxy can do it! Simply refer to the whole documentation.
Cookie
When the user will reach the GALAXY group (using http://aaa.bbb.ccc.ddd), the cookie GALAXY will be created and the server ID specified for "cookie" in the servers definitions will be stored in it (GALAXY_SERVER_01 or GALAXY_SERVER_02).
Then, for the whole session, HAProxy will read the cookie and force the use of the server stored in it.
This behavior is controlled by the "cookie GALAXY insert" line and the "cookie GALAXY_SERVER_XX" parts in the GALAXY group block. If you don't want this feature, simply remove or comment (using a "#") these parts.
Stats
There's a pretty complete load balancer stats page built-in HAProxy. You can reach it there:
http://aaa.bbb.ccc.ddd/haproxy?stats
With the configuration above, the username will be "myuser" and the password "mypass". If you don't want the stats to be enabled, you can simply remove or comment these lines:
Nginx
In the configuration above, we used the port 8080 for the local/private Web servers. If these Web servers are running Nginx, you will need to include the following configuration in your http, server or location block (nginx.conf):
This is needed because if you try to reach this:
http://aaa.bbb.ccc.ddd/test (NO ending slash)
Then Nginx will try to redirect you there:
http://aaa.bbb.ccc.ddd:8080/test/
Which will obviously not work. So if you're running Nginx and that you decided to use a port different of 80, you will need this setting.
6. Starting HAProxy
To start HAProxy, simply issue the following command:
For the initial testing, you might want to disable the cookie in the configuration file and test your Web page to actually see that you're switching from a server to another.
Conclusion
That's it! You've got a high-performance, high-scalability and highly-tweakable load balancer configured in a couple of minutes!
This post will explain how to install HAProxy on FreeBSD and how to configure it as a simple HTTP load balancer.
1. Getting HAproxy
The first step is to download HAProxy. You can find the latest version at this address:
http://haproxy.1wt.eu/#down
As of writing this post, the latest version is 1.3.16, which you can find here:
http://haproxy.1wt.eu/download/1.3/s...-1.3.16.tar.gz
2. Prepare for installation
Log on your FreeBSD machine and change to the temporary directory of your choice. You can now issue the easy following commands:
$ wget http://haproxy.1wt.eu/download/1.3/s...-1.3.16.tar.gz
$ tar xvfz haproxy-1.3.16.tar.gz
$ cd haproxy-1.3.16
$ tar xvfz haproxy-1.3.16.tar.gz
$ cd haproxy-1.3.16
HAProxy is now downloaded, unpacked and ready to be compiled.
3. Compile HAProxy
If you are running FreeBSD, you can simply issue the following command:
$ make -f Makefile.bsd REGEX=pcre DEBUG= COPTS.generic="-Os -fomit-frame-pointer"
If you are running another version of Linux, please refer to the README file (included with HAProxy) to find the good way to compile HAProxy on your system.
4. Install HAProxy
Once HAProxy is compiled, you will find a light-weight, standalone "haproxy" executable.
You can copy it where you want, it's your choice! Something like this can be a good choice:
$ cp haproxy /usr/local/sbin
Why? Simply because /usr/local/sbin is usually in $PATH, so haproxy will then be easy to run simply by typing "haproxy".
5. Configuring HAProxy
The configuration of HAProxy, like its installation, is really easy. In fact, it can be very easy, or very complex. HAProxy is VERY flexible and it has literally thousands of parameters you can tweak. You can find the whole documentation on the HAProxy official Web site there:
http://haproxy.1wt.eu/#docs
As of writing this post, the latest official documentation is there:
http://haproxy.1wt.eu/download/1.3/d...figuration.txt
For this post, we'll keep it simple and configure a simple load balancer.
You can put the HAProxy configuration file where you wish, and name it as you wish! This post will be using this path/filename:
/etc/haproxy.conf
And here's our simple configuration file:
global
maxconn 4096
pidfile /var/run/haproxy.pid
daemon
defaults
mode http
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen GALAXY aaa.bbb.ccc.ddd:80
mode http
cookie GALAXY insert
balance roundrobin
option httpclose
option forwardfor
stats enable
stats auth myuser:mypass
server EARTH 192.168.0.2:8080 cookie GALAXY_SERVER_01 check
server MOON 192.168.0.3:8080 cookie GALAXY_SERVER_02 check
> aaa.bbb.ccc.ddd should be the public IP of your server.
> 192.168.0.2 should be the LAN IP to your server 1.
> 192.168.0.3 should be the LAN IP to your server 2.
Everything that is in CAPS is customizable:
* GALAXY
* EARTH
* MOON
* GALAXY_SERVER_01
* GALAXY_SERVER_02
* EARTH
* MOON
* GALAXY_SERVER_01
* GALAXY_SERVER_02
Basically, this configuration file is defining a group ("listen" block) called GALAXY, which contains 2 servers: EARTH and MOON. The "roundrobin" balance option is telling to HAProxy to alternate between the 2 servers all the time. For the other options in the global, defaults and listen blocks, they're pretty standard. If you need to tweak those or to add options to suit your needs, I'm sure HAProxy can do it! Simply refer to the whole documentation.
Cookie
When the user will reach the GALAXY group (using http://aaa.bbb.ccc.ddd), the cookie GALAXY will be created and the server ID specified for "cookie" in the servers definitions will be stored in it (GALAXY_SERVER_01 or GALAXY_SERVER_02).
Then, for the whole session, HAProxy will read the cookie and force the use of the server stored in it.
This behavior is controlled by the "cookie GALAXY insert" line and the "cookie GALAXY_SERVER_XX" parts in the GALAXY group block. If you don't want this feature, simply remove or comment (using a "#") these parts.
Stats
There's a pretty complete load balancer stats page built-in HAProxy. You can reach it there:
http://aaa.bbb.ccc.ddd/haproxy?stats
With the configuration above, the username will be "myuser" and the password "mypass". If you don't want the stats to be enabled, you can simply remove or comment these lines:
stats enable
stats auth myuser:mypass
stats auth myuser:mypass
Nginx
In the configuration above, we used the port 8080 for the local/private Web servers. If these Web servers are running Nginx, you will need to include the following configuration in your http, server or location block (nginx.conf):
port_in_redirect off;
This is needed because if you try to reach this:
http://aaa.bbb.ccc.ddd/test (NO ending slash)
Then Nginx will try to redirect you there:
http://aaa.bbb.ccc.ddd:8080/test/
Which will obviously not work. So if you're running Nginx and that you decided to use a port different of 80, you will need this setting.
6. Starting HAProxy
To start HAProxy, simply issue the following command:
haproxy -f /etc/haproxy.conf
For the initial testing, you might want to disable the cookie in the configuration file and test your Web page to actually see that you're switching from a server to another.
Conclusion
That's it! You've got a high-performance, high-scalability and highly-tweakable load balancer configured in a couple of minutes!
![]() |
Mike Peters, 07-17-2009 |
One great things about HAProxy is that it supports several load-balancing algorithms:
* Simple round robin (traffic divided equally)
* Least connections (server with least connections gets the request)
and our favorite -
* Source (The source IP address is hashed and divided by the total weight of the running servers to designate which server will receive the request)
The source algorithm ensures that the same client IP address will always reach the same server as long as no server goes down or up. Very important when using HAProxy to load balance databases and avoid replication latencies.
* Simple round robin (traffic divided equally)
* Least connections (server with least connections gets the request)
and our favorite -
* Source (The source IP address is hashed and divided by the total weight of the running servers to designate which server will receive the request)
The source algorithm ensures that the same client IP address will always reach the same server as long as no server goes down or up. Very important when using HAProxy to load balance databases and avoid replication latencies.
![]() |
Patrick, 11-04-2009 |
Nice and sweet ...
Thanks for this mini howto !
I use it and I have a 3 web node load balancing running as expected :-)
Thanks for this mini howto !
I use it and I have a 3 web node load balancing running as expected :-)
![]() |
Willy Tarreau, 01-31-2010 |
Nice article. You could improve your cookie setting by adding "indirect" so that it is not inserted in response to requests that already had it.
Also, I'd like to point your visitors to a more recent version because 1.3.16 has numerous bugs, and I see in my referrers that it's still regularly linked to from your article. Please use 1.3.23 instead : http://haproxy.1wt.eu/download/1.3/s...-1.3.23.tar.gz
Also, I'd like to point your visitors to a more recent version because 1.3.16 has numerous bugs, and I see in my referrers that it's still regularly linked to from your article. Please use 1.3.23 instead : http://haproxy.1wt.eu/download/1.3/s...-1.3.23.tar.gz
![]() |
Mike Peters, 03-28-2010 |
When using HAProxy to load-balance Java Lucene servers, we noticed an interesting problem -
Java File Handlers were leaking.
On every single "hit" from HAProxy to check the status of the Java server, about 10 descriptors leaked and were never released by the garbage collector.
We even tried invoking the garbage collector with .gc() but nothing worked. This appeared to be the case with any Java HttpServer, including the bare bones one provided as part of the documentation.
The only thing that fixed it, was adding this option to HAProxy configuration file:
From HAProxy's documentation:
If you experience a problem with descriptor leaks, try this option and it may work for you as well.
For your reference, this is the complete HAProxy configuration file we used. Removing the "option nolinger" line causes descriptors to leak like crazy:
Java File Handlers were leaking.
On every single "hit" from HAProxy to check the status of the Java server, about 10 descriptors leaked and were never released by the garbage collector.
We even tried invoking the garbage collector with .gc() but nothing worked. This appeared to be the case with any Java HttpServer, including the bare bones one provided as part of the documentation.
The only thing that fixed it, was adding this option to HAProxy configuration file:
option nolinger
From HAProxy's documentation:
Quote:
|
It is possible to disable the system's lingering of data unacked by the client at the end of a session. This is sometimes required when haproxy is used as a front-end with lots of unreliable clients, and you observe thousands of sockets in the FIN_WAIT state on the machine. This may be used in a frontend to affect the client-side connection, as well as in a backend for the server-side connection : option nolinger # disables data lingering |
If you experience a problem with descriptor leaks, try this option and it may work for you as well.
For your reference, this is the complete HAProxy configuration file we used. Removing the "option nolinger" line causes descriptors to leak like crazy:
global
maxconn 1024
pidfile /var/run/haproxy_lucene.pid
daemon
defaults
mode http
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen LUCENE 198.0.0.3:666
mode http
cookie Lucene insert
balance source
option httpclose
option allbackups
option forwardfor
option nolinger
stats enable
server EAST 198.0.0.1:66 check inter 1000
server WEST 198.0.0.2:66 check inter 1000 backup
maxconn 1024
pidfile /var/run/haproxy_lucene.pid
daemon
defaults
mode http
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen LUCENE 198.0.0.3:666
mode http
cookie Lucene insert
balance source
option httpclose
option allbackups
option forwardfor
option nolinger
stats enable
server EAST 198.0.0.1:66 check inter 1000
server WEST 198.0.0.2:66 check inter 1000 backup
![]() |
Philip, 08-25-2010 |
Is it possible to specify a balancing algorithm, aside from round robin, which distributes web requests based on a pre-set percentage, like 70/30 or 90/10 (with control over which server gets what), instead of 50/50, assuming one was balancing a site off of two servers?
Thanks,
Philip
Thanks,
Philip
![]() |
Philip, 08-26-2010 |
... and how about SSL traffic please?
How does one loadbalance a site off 2 IIS7 servers to include SSL traffic also?
Both servers have the SSL cert. installed locally for the (same) site, but we're having issues getting this to work. Anyone know how this is done if possible?
Thanks again,
Philip
How does one loadbalance a site off 2 IIS7 servers to include SSL traffic also?
Both servers have the SSL cert. installed locally for the (same) site, but we're having issues getting this to work. Anyone know how this is done if possible?
Thanks again,
Philip
![]() |
Mike Peters, 08-31-2010 |
Philip,
In my experience SSL traffic doesn't load balance that easily.
In my experience SSL traffic doesn't load balance that easily.
![]() |
Shailendra Singh, 09-03-2010 |
#Hi I will show you step by step Haproxy & Stunnel configuration on RHEL and CentOS, it will cover https configuration as well :
#Fisrt HAPROXY:
#1. Download the Latest Haproxy tar file. extract it anywhere. i.e. /usr/local/HAPROXY 1.4.8.
#change the directory to /usr/local/haproxy/
#then compile the Haproxy with following command.
make TARGET=linux26
#then copy the HAPROXY command #under /usr/local/sbin
cp haproxy /usr/local/sbin/
#Time to change the Haproxy configuration file #under /etc/haproxy.conf
# Before that you need to install Stunnel for Https because i will show yout he both configuration http and #https under haproxy.conf
#take the tar file from stunnel.org
#Extract it and install according to above mention blog.
#generate the key file ( for this you need to install openSSL)
openssl genrsa -rand /dev/urandom -out server.key 2048
#Then you need to generate the CSR ( certifcate sigining request)
openssl req -new -key server.key -out www.xyz.com.csr
#which you will need to upload any certifcate provider i.e verisign.. godaddy. to get the certificate.
#then got the sertifcate from then and put it under directory where you have server.key
#that path you need to put in stunnel configuration file
#sample of Stunnel configuration file under /etc/stunnel/stunnel.conf
sslVersion = all
options = NO_SSLv2
setuid = root
setgid = stunnel
pid = /var/run/stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
output = /var/log/stunnel.log
[www.xyz.com]
cert = /etc/stunnel/cert/intermediate.crt
cert = /etc/stunnel/cert/server.crt
key = /etc/stunnel/cert/server.key
accept = 192.168.0.12:443
connect = 192.168.0.12:81
xforwardedfor = yes
TIMEOUTclose = 0
#Then change the Haproxy configuration file
#Under /etc/haproxy.conf
global
daemon
maxconn 10000
nbproc 2
log 127.0.0.1 syslog
defaults
log global
clitimeout 60000
srvtimeout 30000
contimeout 4000
retries 3
option redispatch
option httpclose
option abortonclose
listen domain_cluster_http 192.168.0.12:80
mode http
balance roundrobin
cookie SERVERID insert nocache
option forwardfor except 192.168.0.12
reqadd X-Forwarded-Proto:\ http
server server1 192.168.0.10:80 cookie s1 weight 1 maxconn 5000 check
server server2 192.168.0.11:80 cookie s2 weight 1 maxconn 5000 check
listen domain_cluster_https 192.168.0.12:81
mode http
balance roundrobin
cookie SERVERID insert nocache
option forwardfor except 192.168.0.12
reqadd X-Forwarded-Proto:\ https
server server1 192.168.0.10:81 cookie s1 weight 1 maxconn 5000 check
server server2 192.168.0.11:81 cookie s2 weight 1 maxconn 5000 check
#Fisrt HAPROXY:
#1. Download the Latest Haproxy tar file. extract it anywhere. i.e. /usr/local/HAPROXY 1.4.8.
#change the directory to /usr/local/haproxy/
#then compile the Haproxy with following command.
make TARGET=linux26
#then copy the HAPROXY command #under /usr/local/sbin
cp haproxy /usr/local/sbin/
#Time to change the Haproxy configuration file #under /etc/haproxy.conf
# Before that you need to install Stunnel for Https because i will show yout he both configuration http and #https under haproxy.conf
#take the tar file from stunnel.org
#Extract it and install according to above mention blog.
#generate the key file ( for this you need to install openSSL)
openssl genrsa -rand /dev/urandom -out server.key 2048
#Then you need to generate the CSR ( certifcate sigining request)
openssl req -new -key server.key -out www.xyz.com.csr
#which you will need to upload any certifcate provider i.e verisign.. godaddy. to get the certificate.
#then got the sertifcate from then and put it under directory where you have server.key
#that path you need to put in stunnel configuration file
#sample of Stunnel configuration file under /etc/stunnel/stunnel.conf
sslVersion = all
options = NO_SSLv2
setuid = root
setgid = stunnel
pid = /var/run/stunnel.pid
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
output = /var/log/stunnel.log
[www.xyz.com]
cert = /etc/stunnel/cert/intermediate.crt
cert = /etc/stunnel/cert/server.crt
key = /etc/stunnel/cert/server.key
accept = 192.168.0.12:443
connect = 192.168.0.12:81
xforwardedfor = yes
TIMEOUTclose = 0
#Then change the Haproxy configuration file
#Under /etc/haproxy.conf
global
daemon
maxconn 10000
nbproc 2
log 127.0.0.1 syslog
defaults
log global
clitimeout 60000
srvtimeout 30000
contimeout 4000
retries 3
option redispatch
option httpclose
option abortonclose
listen domain_cluster_http 192.168.0.12:80
mode http
balance roundrobin
cookie SERVERID insert nocache
option forwardfor except 192.168.0.12
reqadd X-Forwarded-Proto:\ http
server server1 192.168.0.10:80 cookie s1 weight 1 maxconn 5000 check
server server2 192.168.0.11:80 cookie s2 weight 1 maxconn 5000 check
listen domain_cluster_https 192.168.0.12:81
mode http
balance roundrobin
cookie SERVERID insert nocache
option forwardfor except 192.168.0.12
reqadd X-Forwarded-Proto:\ https
server server1 192.168.0.10:81 cookie s1 weight 1 maxconn 5000 check
server server2 192.168.0.11:81 cookie s2 weight 1 maxconn 5000 check
![]() |
Mike Peters, 11-12-2010 |
Using HAProxy to load balance NGinx with PHP-FastCGI?
When in HTTP mode HAProxy's default health check is a simple OPTIONS request. This has the advantage of being a very lightweight request, and is easy to identify and filter from server logs.
Consider this scenario though: HAProxy balances the load between several web servers running nginx and PHP-FastCGI. If nginx is up but PHP-FastCGI goes down, nginx will still properly handle the OPTIONS request from HAProxy, giving the impression that all is well.
HAProxy continues sending requests to the ill server which in turn get a 504 Gateway Timeout (or similar) response. Not a very good situation.
A solution would be to use a deeper health check, one that goes beyond nginx to the PHP-FastCGI process.
That way if PHP-FastCGI goes down, the whole server is presumed 'down'.
When in HTTP mode HAProxy's default health check is a simple OPTIONS request. This has the advantage of being a very lightweight request, and is easy to identify and filter from server logs.
Consider this scenario though: HAProxy balances the load between several web servers running nginx and PHP-FastCGI. If nginx is up but PHP-FastCGI goes down, nginx will still properly handle the OPTIONS request from HAProxy, giving the impression that all is well.
HAProxy continues sending requests to the ill server which in turn get a 504 Gateway Timeout (or similar) response. Not a very good situation.
A solution would be to use a deeper health check, one that goes beyond nginx to the PHP-FastCGI process.
That way if PHP-FastCGI goes down, the whole server is presumed 'down'.
backend appservers
mode http
option httpchk HEAD /health_check.php HTTP/1.1\r\nHost:\ hostname.com
mode http
option httpchk HEAD /health_check.php HTTP/1.1\r\nHost:\ hostname.com
![]() |
Musa, 06-23-2011 |
Hello Mike,
Thanks for this good how to.
i have followed each and every step on ubuntu distro however when i try to compile the haproxy.cfg file, it gives an error:
[ALERT] 173/133753 (1272) : Starting proxy GALAXY: cannot bind socket
Kindly help me in this case.
Regards.
Thanks for this good how to.
i have followed each and every step on ubuntu distro however when i try to compile the haproxy.cfg file, it gives an error:
[ALERT] 173/133753 (1272) : Starting proxy GALAXY: cannot bind socket
Kindly help me in this case.
Regards.
![]() |
Me, 08-09-2011 |
Musa,
You're binding to an IP:Port combination that is either already in use or not present on your system. Look at your frontend / listen directives and fix them up accordingly.
You're binding to an IP:Port combination that is either already in use or not present on your system. Look at your frontend / listen directives and fix them up accordingly.
|
|
Subscribe Now to receive new posts via Email as soon as they come out.
Comments
Post your comments








