Operations 30 min read

Master HAProxy: From Basics to High-Availability L7/L4 Load Balancing

This comprehensive guide explains what HAProxy is, its core functions and key features, then walks through installing, configuring, and running both L7 and L4 load balancers on Linux, adding logging, log rotation, monitoring, and achieving high availability with Keepalived.

Efficient Ops
Efficient Ops
Efficient Ops
Master HAProxy: From Basics to High-Availability L7/L4 Load Balancing

What is HAProxy

HAProxy is a free load‑balancing software that runs on most mainstream Linux operating systems, offering both L4 (TCP) and L7 (HTTP) load‑balancing capabilities with a rich feature set.

The community is very active, with rapid releases (the latest stable 1.7.2 was released on 2017‑01‑13) and performance comparable to commercial load balancers, making it the de‑facto choice for many deployments.

Core Functions

Load balancing: L4 and L7 modes, supporting algorithms such as round‑robin, static‑RR, least‑connection, IP‑hash, URI‑hash, HTTP‑header‑hash, etc.

Health checks: TCP and HTTP modes.

Session persistence: Insert, rewrite, or prefix cookies combined with various hash methods.

SSL termination: HAProxy can decrypt HTTPS and forward plain HTTP to back‑ends.

HTTP request rewriting and redirection.

Monitoring and statistics: a web‑based stats page provides health status and traffic data.

Key Features

Performance

Single‑threaded, event‑driven, non‑blocking model processes hundreds of requests within 1 ms, using only a few kilobytes of memory per session.

O(1) event checking, zero‑copy forwarding and other optimizations keep CPU usage low even under moderate load.

Typical CPU usage is about 15 % for HAProxy itself, with the kernel handling the rest.

In 2009 a test showed a single HAProxy process handling over 100 k requests/second and saturating a 10 Gbps link.

Stability

Running HAProxy as a single process, the author claims no crash‑inducing bugs in 13 years; stability largely depends on the underlying Linux kernel (2.6 or 3.x recommended) and sufficient host memory.

Use a Linux 3.x kernel.

Dedicate the host to HAProxy to avoid resource contention.

Provide a standby machine for hardware failures.

Initial sysctl settings (example below) can be used as a starting point.

<code>net.ipv4.tcp_tw_reuse = 1</code>
<code>net.ipv4.ip_local_port_range = 1024 65023</code>
<code>net.ipv4.tcp_max_syn_backlog = 10240</code>
<code>net.ipv4.tcp_max_tw_buckets = 400000</code>
<code>net.ipv4.tcp_max_orphans = 60000</code>
<code>net.ipv4.tcp_synack_retries = 3</code>
<code>net.core.somaxconn = 10000</code>

Installation and Running on CentOS 7

Create a dedicated user and group (e.g.,

ha

), download, extract, compile, and install HAProxy:

<code>wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.2.tar.gz</code>
<code>tar -xzf haproxy-1.7.2.tar.gz</code>
<code>make PREFIX=/home/ha/haproxy TARGET=linux2628</code>
<code>make install PREFIX=/home/ha/haproxy</code>

Set

PREFIX

to the installation path and

TARGET

according to the kernel version (e.g.,

linux2628

for Linux 3.10).

Create HAProxy Configuration File

<code>global
    daemon
    maxconn 256
    pidfile /home/ha/haproxy/conf/haproxy.pid

defaults
    mode http
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms
    option httpchk GET /healthCheck.html

frontend http-in
    bind *:8080
    default_backend servers

backend servers
    balance roundrobin
    server server1 127.0.0.1:8000 maxconn 32 check
</code>

Ensure

ulimit -n

is greater than

maxconn*2+18

for large connection limits.

Register HAProxy as a System Service

<code>#!/bin/sh
set -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/home/ha/haproxy/sbin
PROGDIR=/home/ha/haproxy
PROGNAME=haproxy
DAEMON=$PROGDIR/sbin/$PROGNAME
CONFIG=$PROGDIR/conf/$PROGNAME.cfg
PIDFILE=$PROGDIR/conf/$PROGNAME.pid
DESC="HAProxy daemon"
SCRIPTNAME=/etc/init.d/$PROGNAME

# Gracefully exit if the binary is missing.
[ -x $DAEMON ] || exit 0

start() {
    echo "Starting $DESC: $PROGNAME"
    $DAEMON -f $CONFIG
}

stop() {
    echo "Stopping $DESC: $PROGNAME"
    haproxy_pid="$(cat $PIDFILE)"
    kill $haproxy_pid
}

restart() {
    echo "Restarting $DESC: $PROGNAME"
    $DAEMON -f $CONFIG -p $PIDFILE -sf $(cat $PIDFILE)
}

case "$1" in
    start) start ;;
    stop)  stop  ;;
    restart) restart ;;
    *) echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2; exit 1 ;;
esac
exit 0
</code>

Running HAProxy

Start, stop, or restart with:

<code>service haproxy start</code>
<code>service haproxy stop</code>
<code>service haproxy restart</code>

Logging with rsyslog

Add to

haproxy.cfg

:

<code>global
    ...
    log 127.0.0.1 local0 info
    log 127.0.0.1 local1 warning

defaults
    ...
    log global
</code>

Configure

/etc/rsyslog.d/haproxy.conf

to write logs to

/var/log/haproxy.log

(local0) and

/var/log/haproxy_warn.log

(local1), then restart rsyslog and HAProxy.

Log Rotation

<code>/var/log/haproxy.log /var/log/haproxy_warn.log {
    daily
    rotate 7
    create 0644 ha ha
    compress
    delaycompress
    missingok
    dateext
    sharedscripts
    postrotate
        /bin/kill -HUP $(/bin/cat /var/run/syslogd.pid 2>/dev/null) >/dev/null 2>&1
    endscript
}
</code>

Schedule with a daily cron job.

Building an L7 Load Balancer

Architecture (illustrated below):

Deploy six backend Nginx services (three groups: ms1, ms2, def) on two hosts, each serving a simple

demo.html

page and a

healthCheck.html

page.

HAProxy Configuration for L7

<code>global
    daemon
    maxconn 30000
    user ha
    pidfile /home/ha/haproxy/conf/haproxy.pid
    log 127.0.0.1 local0 info
    log 127.0.0.1 local1 warning

defaults
    mode http
    log global
    option http-keep-alive
    option forwardfor
    option httplog
    timeout connect 5000ms
    timeout client 10000ms
    timeout server 50000ms
    timeout http-request 20000ms
    option httpchk GET /healthCheck.html

frontend http-in
    bind *:9001
    acl url_ms1 path_beg -i /ms1/
    acl url_ms2 path_beg -i /ms2/
    use_backend ms1 if url_ms1
    use_backend ms2 if url_ms2
    default_backend default_servers

backend ms1
    balance roundrobin
    cookie HA_STICKY_ms1 insert indirect nocache
    server ms1.srv1 192.168.8.111:8080 cookie ms1.srv1 maxconn 300 check inter 2000ms rise 2 fall 3
    server ms1.srv2 192.168.8.112:8080 cookie ms1.srv2 maxconn 300 check

backend ms2
    balance roundrobin
    cookie HA_STICKY_ms2 insert indirect nocache
    server ms2.srv1 192.168.8.111:8081 cookie ms2.srv1 maxconn 300 check
    server ms2.srv2 192.168.8.112:8081 cookie ms2.srv2 maxconn 300 check

backend default_servers
    balance roundrobin
    cookie HA_STICKY_def insert indirect nocache
    server def.srv1 192.168.8.111:8082 cookie def.srv1 maxconn 300 check
    server def.srv2 192.168.8.112:8082 cookie def.srv2 maxconn 300 check

listen stats
    bind *:1080
    stats refresh 30s
    stats uri /stats
    stats realm "HAProxy Stats"
    stats auth admin:admin
</code>

After starting HAProxy, the stats page (

http://<host>:1080/stats

) shows health, connections, session rates, and backend status.

Building an L4 Load Balancer

In L4 mode HAProxy does not parse HTTP, so features like URI‑based routing and cookie persistence are unavailable, but performance is higher for raw TCP services.

<code>global
    daemon
    maxconn 30000
    user ha
    pidfile /home/ha/haproxy/conf/haproxy.pid
    log 127.0.0.1 local0 info
    log 127.0.0.1 local1 warning

defaults
    mode tcp
    log global
    option tcplog
    timeout connect 5000ms
    timeout client 10000ms
    timeout server 10000ms
    option httpchk GET /healthCheck.html

frontend http-in
    bind *:9002
    default_backend default_servers

backend default_servers
    balance roundrobin
    server def.srv1 192.168.8.111:8082 maxconn 300 check
    server def.srv2 192.168.8.112:8082 maxconn 300 check
</code>

For source‑IP persistence replace

balance roundrobin

with

balance source

or use stick‑tables.

Key Configuration Details

Global Section

daemon

: run HAProxy in background.

user

/

group

: drop privileges.

log

: send logs to rsyslog.

pidfile

: store process ID.

maxconn

: maximum concurrent connections.

Frontend Section

acl

: define boolean conditions (e.g., URI prefixes).

bind

: listen address and port.

default_backend

: fallback backend.

use_backend … if

: conditional routing.

option forwardfor

,

option http‑keep‑alive

,

option httplog

, etc.

Backend Section

balance

: load‑balancing algorithm (roundrobin, source, etc.).

cookie

: enable cookie‑based persistence.

server

: define each backend server with parameters such as

check

,

maxconn

,

cookie

, etc.

Default Section

Common parameters that apply to all frontends and backends unless overridden.

Listen Section

Combines frontend and backend in a single block for simpler configurations.

High Availability with Keepalived

Deploy Keepalived on two HAProxy hosts to share a virtual IP. The instance with higher weight becomes MASTER; if it fails, the BACKUP takes over.

<code>global_defs {
    router_id LVS_DEVEL
}

vrrp_script chk_haproxy {
    script "killall -0 haproxy"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface enp0s25
    virtual_router_id 51
    priority 101
    advert_int 1
    virtual_ipaddress {
        192.168.8.201
    }
    track_script {
        chk_haproxy
    }
}
</code>

Install Keepalived, register it as a service, and start it on both machines. The virtual IP will move to the backup host automatically when the master HAProxy or Keepalived instance stops, ensuring continuous service.

High AvailabilityLoad BalancingconfigurationLinuxHAProxyKeepalivedL7L4
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.