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 very high traffic web sites and powers quite a number of the world’s most visited ones. Over the years it has become the de-facto standard opensource load balancer, is now shipped with most mainstream Linux distributions, and is often deployed by default in cloud platforms.
Performance:
A) A single-process, event-driven model considerably reduces the cost of context switch and the memory usage. Processing several hundreds of tasks in a millisecond is possible, and the memory usage is in the order of a few kilobytes per session while memory consumed in preforked or threaded servers is more in the order of megabytes per process.
B) O(1) event checker on systems that allow it (Linux and FreeBSD) allowing instantaneous detection of any event on any connection among tens of thousands.
c) Delayed updates to the event checker using a lazy event cache ensures that we never update an event unless absolutely required. This saves a lot of system calls.
D) Single-buffering without any data copy between reads and writes whenever possible. This saves a lot of CPU cycles and useful memory bandwidth. Often, the bottleneck will be the I/O busses between the CPU and the network interfaces. At 10-100 Gbps, the memory bandwidth can become a bottleneck too.
E) Zero-copy forwarding is possible using the splice() system call under Linux, and results in real zero-copy starting with Linux 3.5. This allows a small sub-3 Watt device such as a Seagate Dockstar to forward HTTP traffic at one gigabit/s.
F) MRU memory allocator using fixed size memory pools for immediate memory allocation favoring hot cache regions over cold cache ones. This dramatically reduces the time needed to create a new session.
G) Work factoring, such as multiple accept() at once, and the ability to limit the number of accept() per iteration when running in multi-process mode, so that the load is evenly distributed among processes.
H) CPU-affinity is supported when running in multi-process mode, or simply to adapt to the hardware and be the closest possible to the CPU core managing the NICs while not conflicting with it.
I) Tree-based storage, making heavy use of the Elastic Binary tree I have been developping for several years. This is used to keep timers ordered, to keep the runqueue ordered, to manage round-robin and least-conn queues, to look up ACLs or keys in tables, with only an O(log(N)) cost.
J) Optimized timer queue : timers are not moved in the tree if they are postponed, because the likeliness that they are met is close to zero since they’re mostly used for timeout handling. This further optimizes the ebtree usage.
K) optimized HTTP header analysis : headers are parsed an interpreted on the fly, and the parsing is optimized to avoid an re-reading of any previously read memory area. Checkpointing is used when an end of buffer is reached with an incomplete header, so that the parsing does not start again from the beginning when more data is read. Parsing an average HTTP request typically takes half a microsecond on a fast Xeon E5.
L) careful reduction of the number of expensive system calls. Most of the work is done in user-space by default, such as time reading, buffer aggregation, file-descriptor enabling/disabling.
M) Content analysis is optimized to carry only pointers to original data and never copy unless the data needs to be transformed. This ensures that very small structures are carried over and that contents are never replicated when not absolutely necessary.
How to Install
1) Login to ssh (using putty).
2) Download haproxy on your server (1.5.11 stable release).
wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.11.tar.gz tar zxvf haproxy-1.5.11.tar.gz cd haproxy-1.5.11 make install cp /usr/local/sbin/haproxy /usr/sbin/ cp /root/haproxy-1.5.11/examples/haproxy.init /etc/init.d/haproxy chmod 755 /etc/init.d/haproxy useradd --system haproxy mkdir /etc/haproxy cd /etc/haproxy
3) Now setup haproxy config file. Create haproxy.cfg in /etc/haproxy and add the config file below.
nano haproxy.cfg
global daemon maxconn 20000 # count about 1 GB per 20000 connections pidfile /var/run/haproxy.pid stats socket /var/run/haproxy.stat mode 600 defaults mode http maxconn 19500 # Should be slightly smaller than global.maxconn. timeout client 60s # Client and server timeout must match the longest timeout server 60s # time we may wait for a response from the server. timeout queue 60s # Don't queue requests too long if saturated. timeout connect 10s # There's no reason to change this one. timeout http-request 10s # A complete request may never take that long. # Uncomment the following one to protect against nkiller2. But warning! # some slow clients might sometimes receive truncated data if last # segment is lost and never retransmitted : # option nolinger option http-server-close option abortonclose balance roundrobin option forwardfor # set the client's IP in X-Forwarded-For. option tcp-smart-accept option tcp-smart-connect retries 2 frontend public bind your-ip-address:80 # table used to store behaviour of source IPs stick-table type ip size 200k expire 5m store gpc0,conn_rate(10s) # IPs that have gpc0 > 0 are blocked until the go away for at least 5 minutes acl source_is_abuser src_get_gpc0 gt 0 tcp-request connection reject if source_is_abuser # connection rate abuses get blocked acl conn_rate_abuse sc1_conn_rate gt 30 acl mark_as_abuser sc1_inc_gpc0 gt 0 tcp-request connection track-sc1 src tcp-request connection reject if conn_rate_abuse mark_as_abuser default_backend apache backend apache # set the maxconn parameter below to match Apache's MaxClients minus # one or two connections so that you can still directly connect to it. server srv 0.0.0.0:8181 maxconn 254 # Enable the stats page on a dedicated port (8182). Monitoring request errors # on the frontend will tell us how many potential attacks were blocked. listen stats # Uncomment "disabled" below to disable the stats page : # disabled bind :8182 stats uri / stats auth bullten:bullten
In above config file change your-ip-address with your server ip. If you have multiple ip address, add all in the same format in new line.
eg:
frontend public bind your-ip-address:80 bind your-ip-address-2:80 bind your-ip-address-3:80
In the above config file new apache port has been set to 8181. To change port, find line srv 0.0.0.0:8181 maxconn 254 and replace 8181 with the port you want.
A web statics interface is accessible using http://yourip:8182 using user and password (bullten:bullten). If you want to change its port and authentication data then find line bind :8182 and change port. For authentication find stats auth bullten:bullten and change its username and password respectively.
4) Now we need to change apache port. Login to CentOS Web Panel GUI (http://yourip:2030) and navigate to CWP Settings –> Edit settings and change Apache Port: value to 8181.
5) Restart apache.
service httpd restart
6) Start haproxy and make it to automatically start on server boot.
service haproxy start chkconfig haproxy on
You are done with the setup and your haproxy proxy is now ready to serve apache as reverse proxy. To check statics use http://yourip:8182 and enter the user:pass specified in haproxy.cfg file.
In case you need to restart haproxy use the command below.
service haproxy restart
We have setup haproxy on our test server. You can access at http://cwp.bullten.com:8182 with user: bullten and pass: bullten.
NOTE: You can use Slowloris to check if Haproxy is efficiently blocking it.