# Arsitektur Zero-Downtime HAProxy & Keepalived untuk Beban API Skala Ekstrem

> Diterbitkan oleh Literally Web ID pada 21 Oct 2026
> Sumber: https://literally.web.id/articles/arsitektur-zero-downtime-haproxy-keepalived-untuk-beban-api-skala-ekstrem

---

# 1. Alarm Tengah Malam: Saat Layanan Produksi Mulai Tumbang

Pukul 02.14 WIB. Ponsel saya berdering melengking, memecah keheningan kamar. PagerDuty tidak sekadar memanggil; ia menjerit. Layar ponsel saya menyala terang, memamerkan grafik metrik Prometheus yang terjun bebas layaknya roller coaster tanpa rem. Angka *error rate* HTTP 502 Bad Gateway melonjak dari baseline normal di bawah 0.01% menjadi hampir 45%, sementara latensi rata-rata meroket dari 45 milidetik ke angka 3.200 milidetik. Di ruang kendali virtual, rekan-rekan tim SRE mulai membanjiri kanal Slack insiden dengan kepanikan yang terkontrol. API utama yang melayani jutaan request aplikasi seluler dan integrasi mitra bisnis mendadak megap-megap. Sebagai Principal Systems Architect, malam itu saya tahu ada sesuatu yang benar-benar salah di lapisan terdepan infrastruktur kami.

Lonjakan trafik kampanye akhir bulan memang sudah kami antisipasi, namun kegagalan kali ini terasa berbeda karena tidak ada satupun *backend node* Go atau PHP-FPM kami yang mengalami *OOM Killer* atau kehabisan koneksi database MySQL. Masalahnya terlokalisasi di gerbang utama: klaster ingress load balancer berbasis HAProxy dan Keepalived. Virtual IP (VIP) yang seharusnya melayang mulus di antara node *load balancer* utama dan cadangan tiba-tiba mengalami *split-brain* akibat badai jaringan, membuat ribuan klien mengalami *connection reset*. Sebelum kita masuk ke dalam ruang bedah investigasi log untuk menyelamatkan sistem ini, mari kita pahami bagaimana fondasi jaringan ini dirancang sejak awal.

# 2. Jejak Digital: Menelusuri Anomali Log & Lonjakan Metrik

Begitu mengambil alih komando insiden, langkah pertama saya bukanlah langsung melakukan *restart* buta, melainkan membuka terminal dan menerobos masuk ke dalam mesin *load balancer* utama melalui SSH. Saya langsung mengarahkan pandangan ke log sistem di `/var/log/syslog` dan mengamati gerak-gerik daemon Keepalived yang bertugas mempertahankan IP *floating*. Di saat yang sama, terminal kedua saya arahkan untuk memantau statistik *socket* TCP menggunakan `ss -s` dan log internal HAProxy.

```bash
# Memantau transisi state VRRP Keepalived secara real-time
tail -f /var/log/syslog | grep -E "Keepalived_vrrp|VRRP"
```

Dari barisan log tersebut, pemandangan mengerikan tersaji nyata. Node primer dan sekunder saling berebut status *MASTER* dalaminterval waktu yang sangat singkat—sebuah fenomena *flapping* VRRP yang dipicu oleh lonjakan paket *broadcast* multicast yang tertahan di switch jaringan tingkat atas. Keepalived terus-menerus mengirimkan paket iklan VRRP, tetapi karena antrean *buffer* kernel penuh, paket tersebut drop, membuat kedua node mengira rekan mereka telah mati. Akibatnya, IP *floating* berpindah-pindah tangan secara liar, memutuskan ribuan koneksi TCP yang sedang aktif berstatus *ESTABLISHED*.

> [!WARNING]
> Jangan pernah mengandalkan konfigurasi *default* VRRP Keepalived untuk lingkungan produksi berskala masif. Interval *advert_int* yang terlalu cepat tanpa penyesuaian parameter *priority* dan *garp_master_delay* adalah resep pasti menuju bencana *split-brain* saat trafik jaringan melonjak.

Tidak berhenti di situ, saya juga memeriksa konfigurasi HAProxy untuk melihat bagaimana ia memperlakukan *health check* ke *backend* pool. Di sinilah letak bom waktu kedua berdetak. Konfigurasi awal kami menggunakan pemeriksaan Layer 4 TCP sederhana yang mengira bahwa selama port 8000 terbuka, maka *backend* sehat walafiat, padahal aplikasi di baliknya sedang mengalami deadlock koneksi database.

# 3. Membongkar Biang Kerok: Akar Masalah yang Sebenarnya

Setelah menarik napas dalam-dalam dan merunut seluruh korelasi metrik dari Grafana, akar permasalahan mulai terkuak secara terang-terang. Ada tiga dosa arsitektural fatal yang kami lakukan pada rancangan sistem ingress ini:

1. **Konfigurasi VRRP Keepalived yang Rapuh**: Kami menggunakan *advert_int 1* tanpa mekanisme proteksi *unicast_peer*, sehingga rentan terhadap gangguan *multicast storm* di switch fisik pusat data.
2. **Pencampuran Layer 4 dan Layer 7 yang Keliru**: HAProxy dikonfigurasi menggunakan mode TCP murni (`mode tcp`) untuk beberapa rute API krusial tanpa memanfaatkan kemampuan analisis HTTP Layer 7 yang cerdas, membuat proxy buta terhadap status respons aktual dari aplikasi.
3. **Health Check Tuning yang Terlalu Agresif**: Pengaturan `rise 2` dan `fall 3` dengan interval 2 detik membuat HAProxy terlalu cepat mendepak *backend* hanya karena satu lonjakan latensi sesaat, memicu efek domino *thundering herd problem* ke sisa server yang masih hidup.

Mari kita bandingkan pendekatan konfigurasi lama yang rapuh dengan arsitektur baru yang tahan banting melalui tabel perbandingan di bawah ini:

| Komponen | Pendekatan Lama (Rapuh) | Pendekatan Baru (Zero-Downtime HA)
| --- | --- | --- |
| **Keepalived Protocol** | Multicast VRRP murni | Unicast VRRP dengan otentikasi AH/PASS |
| **HAProxy Mode** | Mode TCP murni (`mode tcp`) | Layer 7 HTTP pintar (`mode http`) dengan inspeksi URI |
| **Health Check** | TCP Connect sederhana ke Port | HTTP GET `/healthz` dengan validasi payload JSON |
| **Failover Delay** | Instan tanpa penundaan | *Garp master delay* 3 detik + *track_interface*

Transisi dari pemahaman akar masalah ini menuntut aksi nyata yang cepat, terukur, dan langsung berdampak pada pemulihan layanan tanpa menunggu matahari terbit.

# 4. Tindakan Darurat: Menghidupkan Kembali Layanan dalam Hitungan Menit

Sembari menganalisis log, saya mengarahkan tim untuk segera mengeksekusi skrip mitigasi darurat guna menenangkan badai koneksi. Langkah pertama adalah menstabilkan IP *floating* dengan mematikan Keepalived di node sekunder yang bermasalah secara manual, memaksa node primer memegang kendali penuh, lalu memperbarui konfigurasi HAProxy secara *on-the-fly* menggunakan soket manajemen tanpa melakukan *restart* proses.

Berikut adalah eksekusi perintah darurat di terminal yang menyelamatkan sistem kami dalam kurun waktu kurang dari 60 detik:

```bash
# 1. Hentikan sementara Keepalived di node cadangan untuk menghentikan flapping
sudo systemctl stop keepalived

# 2. Paksa node utama mengambil alih VIP dan pastikan interface terikat sempurna
sudo ip addr add 192.168.10.100/24 dev eth0
sudo arping -A -I eth0 -c 3 192.168.10.100

# 3. Perbarui timeout dan matikan backend yang bermasalah via HAProxy Runtime API
echo "disable server api_cluster/backend_node_04" | sudo socat stdio /run/haproxy/admin.sock

# 4. Verifikasi status kesehatan cluster load balancer
echo "show stat" | sudo socat stdio /run/haproxy/admin.sock | cut -d',' -f1,2,5
```

> [!TIP]
> Manfaatkan selalu HAProxy Runtime UNIX Socket (`stats socket`) untuk melakukan *maintenance* atau mematikan *backend* bermasalah secara instan tanpa perlu mengetik perintah `systemctl reload haproxy` yang berisiko menjatuhkan koneksi aktif (*graceful timeout drop*).

Setelah eksekusi perintah tersebut, grafik error 502 langsung melandai turun secara drastis dalam kurun waktu 3 menit, mengembalikan senyum ke wajah seluruh anggota tim on-call. Namun, pekerjaan kami belum selesai; fondasi ini harus ditulis ulang agar tidak menjadi bom waktu di masa depan.

# 5. Kebijakan Retrospektif: Menambal Celah agar Tak Pernah Terulang

Pengalaman hampir melumpuhkan sistem produksi ini melahirkan standar operasional baru yang wajib diterapkan di seluruh klaster infrastruktur kami. Konfigurasi Keepalived kini dirombak total menggunakan mode *unicast* untuk menghindari kebisingan jaringan multicast, dilengkapi dengan skrip *track_script* yang memantau kesehatan proses HAProxy itu sendiri.

Berikut adalah contoh berkas konfigurasi `keepalived.conf` baru yang tangguh, aman, dan telah diuji dalam beban ekstrem:

```ini
global_defs {
    router_id lb_node_primary
    enable_script_security
    script_user root
}

vrrp_script check_haproxy {
    script "/usr/bin/killall -0 haproxy"
    interval 2
    weight 2
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    
    # Menggunakan unicast peer untuk mencegah multicast storm
    unicast_src_ip 192.168.10.11
    unicast_peer {
        192.168.10.12
    }

    authentication {
        auth_type PASS
        auth_pass SecretVrrpPassword2024
    }

    virtual_ipaddress {
        192.168.10.100/24
    }

    track_script {
        check_haproxy
    }
}
```

Tidak kalah penting, konfigurasi HAProxy (`haproxy.cfg`) juga disempurnakan dengan *health check* Layer 7 yang mendalam, pengaturan *timeouts* yang manusiawi, serta algoritma *leastconn* untuk mendistribusikan beban secara merata ke klaster aplikasi:

```haproxy
global
    log /dev/log local0
    log /dev/log local1 notice
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    daemon
    maxconn 100000
    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
    stats timeout 30s

defaults
    log global
    mode http
    option httplog
    option dontlognull
    retries 3
    timeout connect 5s
    timeout client  50s
    timeout server  50s
    timeout queue   1m

frontend api_gateway_front
    bind 192.168.10.100:443 ssl crt /etc/ssl/certs/api_bundle.pem alpn h2,http/1.1
    mode http
    default_backend api_cluster_back

backend api_cluster_back
    balance leastconn
    option httpchk GET /healthz
    http-check expect status 200
    # Tuning ketat agar tidak salah mendepak backend
    default-server inter 5s rise 3 fall 3 slowstart 30s maxconn 2000
    server app_node_01 192.168.10.21:8000 check
    server app_node_02 192.168.10.22:8000 check
    server app_node_03 192.168.10.23:8000 check
```

# 6. Pasang Alarm: Otomasi Deteksi Dini untuk Tim On-Call

Infrastruktur hebat tidak diukur dari seberapa jarang ia gagal, tetapi dari seberapa cepat ia mendeteksi kegagalan sebelum pengguna menyadarinya. Sebagai langkah preventif terakhir, kami membangun sistem pemantauan otomatis menggunakan Prometheus dan Alertmanager yang terintegrasi langsung dengan webhook Slack dan PagerDuty.

Berikut adalah aturan *alerting rule* Prometheus (`alert_rules.yml`) yang secara spesifik memantau kesehatan transisi VRRP dan lonjakan kegagalan *load balancer*:

```yaml
groups:
  - name: haproxy_keepalived_alerts
    rules:
      - alert: KeepalivedStateChanged
        expr: keepalived_vrrp_state != 1
        for: 30s
        labels:
          severity: warning
        annotations:
          summary: "Keepalived state changed on {{ $labels.instance }}"
          description: "Node has transitioned away from MASTER state, potential split-brain risk."

      - alert: HAProxyHighErrorRate
        expr: sum(rate(haproxy_server_http_responses_total{code="5xx"}[1m])) / sum(rate(haproxy_server_http_responses_total[1m])) * 100 > 1
        for: 1m
        severity: critical
        annotations:
          summary: "HAProxy 5xx error rate exceeds 1%"
          description: "API Gateway is returning an unacceptable amount of 5xx errors. Immediate investigation required."

      - alert: HAProxyBackendDown
        expr: haproxy_server_up == 0
        for: 30s
        labels:
          severity: critical
        annotations:
          summary: "Backend server {{ $labels.server }} is down"
          description: "HAProxy health check has marked backend node as DOWN in cluster {{ $labels.backend }}."

      - alert: HAProxyConnectionSaturation
        expr: haproxy_server_current_sessions / haproxy_server_max_sessions * 100 > 85
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "HAProxy connection pool near saturation"
          description: "Backend server {{ $labels.server }} session utilization is above 85%."
```

Dengan sistem alarm otomatis ini, setiap anomali kecil pada transisi VRRP atau lonjakan pemanfaatan sesi akan segera memicu peringatan dini ke tim *on-call*, memastikan malam-malam penuh kepanikan seperti kemarin tidak akan pernah terulang kembali dalam sejarah operasional perusahaan kita.