ตั้งค่า HAProxy Load Balancer บน VPS

เมื่อแอปพลิเคชันของคุณเติบโตและรับภาระงานสูงมากขึ้น ปัญหาที่พบบ่อยคือ server ตัวเดียวรับไม่ไหว วิธีที่ถูกต้องคือสร้าง backend servers หลายตัว แล้วใช้ Load Balancer ซึ่งเป็น reverse proxy ที่รับ traffic มาจัดแจกให้เซิร์ฟเวอร์เหล่านั้น HAProxy เป็น Load Balancer ยอดนิยมที่ใช้โดยจำนวนเว็บไซต์ชั้นนำหลายแห่ง โดยสามารถจัดการ connection หลายหมื่นพร้อมกันได้ในเวลาเดียวกัน พร้อม Health Check อัตโนมัติและ SSL Termination ครบครัน

ทำไมต้องใช้ HAProxy แทน Nginx

Nginx และ HAProxy ต่างก็สามารถทำ load balancing ได้ แต่ HAProxy ดีกว่าในด้านต่อไปนี้ Nginx เป็น web server ที่มี load balancing feature เพิ่มเติม ส่วน HAProxy ถูกออกแบบมาแนวทางเดียวคือจัดการ traffic load balancing และ reverse proxy เท่านั้น

สิ่งที่ต้องมีก่อนเริ่ม

ขั้นที่ 1 — ติดตั้ง HAProxy

# อัพเดต package list
sudo apt update

# ติดตั้ง HAProxy และ Certbot (สำหรับ SSL)
sudo apt install -y haproxy certbot python3-certbot-nginx

# ตรวจสอบเวอร์ชัน
haproxy -v

ต้องได้ผล HAProxy version 2.x ขึ้นไป ถ้าต่ำกว่า 2.0 ให้อัพเดตรุ่นจาก PPA repository

ขั้นที่ 2 — สร้าง Config File หลัก

ไฟล์ config หลักของ HAProxy อยู่ที่ /etc/haproxy/haproxy.cfg ให้เปิดแก้ไขด้วย nano

sudo nano /etc/haproxy/haproxy.cfg

ให้เขียน config นี้แทนเนื้อหาเดิม (แบ็คอัป config เดิมไว้ก่อนนะ):

global
  log stdout local0
  log stdout local1 notice
  chroot /var/lib/haproxy
  stats socket /run/haproxy/admin.sock mode 660 level admin
  stats timeout 30s
  user haproxy
  group haproxy
  daemon
  maxconn 262144              # จำนวน connection สูงสุดที่ HAProxy รับ

  # ตั้งค่า SSL security (A+ rating)
  ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
  ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256

defaults
  log     global
  mode    http
  option  httplog
  option  denyall-on-abort
  timeout connect 5000
  timeout client  50000
  timeout server  50000
  retries 3

# Listener ด้านลูกค้า (frontend)
frontend myweb
  bind *:80
  bind *:443 ssl crt /etc/letsencrypt/live/domain.com/fullchain.pem key /etc/letsencrypt/live/domain.com/privkey.pem

  # Redirect HTTP ไป HTTPS
  http-request redirect scheme https code 301 if !{ ssl_fc }

  # Set header เพื่อบอก backend ว่ามาจาก HTTPS
  http-request set-header X-Forwarded-Proto https if { ssl_fc }

  # Log ทุก request
  option httplog

  # ชื่อ domain (ตัวเลือก)
  capture request header Host len 64

  # Route ไปยัง backend pool
  default_backend webservers

# Listener ด้าน backend servers
backend webservers
  balance roundrobin                        # Round-robin distribution

  # Health check ทุก 5 วินาที
  option httpchk GET /health HTTP/1.1
  http-check expect status 200
  default-server inter 5s fall 2 rise 2

  # Define backend servers
  server backend1 192.168.1.10:8080 check  # IP และ port ของ backend server ตัวที่ 1
  server backend2 192.168.1.11:8080 check  # IP และ port ของ backend server ตัวที่ 2
  server backend3 192.168.1.12:8080 check  # IP และ port ของ backend server ตัวที่ 3

  # Session persistence (Sticky)
  cookie SERVERID insert indirect nocache
  server-template srv 1-10 0.0.0.0:80 disabled cookie srv

# Stats UI (สำหรับดูสถิติ)
listen stats
  bind *:8404
  stats enable
  stats uri /stats
  stats refresh 30s
  stats show-legends

สิ่งสำคัญที่ต้องแก้ไข:

ขั้นที่ 3 — ขอใบ SSL จาก Let's Encrypt

ก่อนจะ start HAProxy ต้องขอใบเซอร์จาก Let's Encrypt ที่ path ที่ config ชี้ไป

# หยุด HAProxy ไว้ก่อน (ถ้ากำลังรัน)
sudo systemctl stop haproxy

# ขอ SSL certificate (เปลี่ยน domain.com และ email)
sudo certbot certonly --standalone -d domain.com -d www.domain.com --email [email protected]

# ตอบ prompt ที่ปรากฏ (ยอมรับ ToS, ใส่ email ฯลฯ)

# ตรวจว่าไฟล์เซอร์อยู่ที่ไหน
ls -la /etc/letsencrypt/live/domain.com/

ต้องได้ 2 ไฟล์สำคัญ: fullchain.pem และ privkey.pem

ขั้นที่ 4 — เปิด HAProxy Service

# ตรวจสอบ config ว่า syntax ถูกต้องหรือไม่
sudo haproxy -c -f /etc/haproxy/haproxy.cfg

# ถ้าไม่มี error ให้ reload service
sudo systemctl enable haproxy
sudo systemctl start haproxy

# ตรวจสอบสถานะ
sudo systemctl status haproxy

# ดู log real-time
sudo tail -f /var/log/haproxy.log

ตรวจสอบ HAProxy ทำงาน: เปิด browser ไปที่ http://IP_ของ_HAProxy:8404/stats จะได้หน้า Statistics ที่แสดงสถานะของ backend servers กำลังได้ request เท่าไร healthy หรือไม่

ขั้นที่ 5 — ตั้ง Sticky Sessions (ถ้าต้องการ)

ถ้าแอปพลิเคชันของคุณเก็บ session ใน server memory เพิ่มเติมเพื่อผูกมัด session ของลูกค้าเดียวกัน:

# แก้ backend pool ใน config
backend webservers
  balance roundrobin
  cookie SERVERID insert indirect nocache

  server backend1 192.168.1.10:8080 check cookie backend1
  server backend2 192.168.1.11:8080 check cookie backend2
  server backend3 192.168.1.12:8080 check cookie backend3

HAProxy จะฉีด cookie ชื่อ SERVERID ไปยัง response แล้ว request ครั้งต่อไปจะใช้ cookie นี้เพื่อกำหนด backend ตัวเดิม

ขั้นที่ 6 — ต่อ SSL Certificate อัตโนมัติ

ใบเซอร์มี validity 90 วัน ต้องต่ออายุอัตโนมัติเพื่อไม่ให้หมดอายุ สร้าง hook script:

# สร้าง renewal hook directory
sudo mkdir -p /etc/letsencrypt/renewal-hooks/post

# เขียน post-renewal script
sudo nano /etc/letsencrypt/renewal-hooks/post/haproxy.sh

ใส่เนื้อหานี้:

#!/bin/bash
# HAProxy SSL Certificate Renewal Hook

# โปรแกรมจะรัน script นี้หลังจากใบเซอร์ต่ออายุสำเร็จ
# ให้ HAProxy reload เพื่อโหลดใบเซอร์ใหม่

systemctl reload haproxy

# ตัวเลือก: ส่ง notification ไปยัง admin
echo "HAProxy SSL certificate renewed for $(date)" | mail -s "SSL Renewed" [email protected]

บันทึกแล้ว Ctrl+X แล้ว:

# ให้ permission ในการรัน
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/haproxy.sh

# ทดสอบ renewal (ใช้เหมือนจริง แต่ไม่ส่ง)
sudo certbot renew --dry-run

Load Balancing Algorithms ต่างๆ

ตัวเลือก balance ใน backend pool มีหลายแบบ:

1. Roundrobin (Default)

balance roundrobin
# ส่ง request ให้ backend ตามลำดับตัวอักษร: server1, server2, server1, server2, ...

2. Least Connection

balance leastconn
# ส่ง request ไปยัง backend ที่มี active connections น้อยที่สุด
# เหมาะกับการรองรับ long-lived connections เช่น WebSocket

3. Source IP Hash

balance source
# Hash IP ของลูกค้า เพื่อให้ลูกค้า IP เดิมไป backend เดิม
# ไม่ต้องใช้ cookie แต่ถ้า backend ลง session จะหาย

Health Check Options

# ตัวอย่าง Health Check ขั้นสูง
backend webservers
  # Check ทุก 5 วินาที, timeout 2 วินาที
  # Fall 3 ครั้ง = ทำให้ server down, Rise 2 ครั้ง = ให้ server ขึ้นมาใหม่
  option httpchk GET /health HTTP/1.1\r\nHost:\ domain.com
  default-server inter 5s fall 3 rise 2 timeout 2s

  server backend1 192.168.1.10:8080 check
  server backend2 192.168.1.11:8080 check slowstart 60s  # ช้าๆ start ใน 60 วินาที

Troubleshooting

HAProxy ไม่ start

# ตรวจ syntax error
sudo haproxy -c -f /etc/haproxy/haproxy.cfg

# ถ้ามี error ให้เอา output มาดู
# ทั่วไปเกิดจากชื่อ domain ผิด, path SSL file ผิด, หรือ port ถูกใช้ไปแล้ว

Backend servers ไม่ตอบ Health Check

# ตรวจว่า backend servers ยังไม่ถูก access บ่อยครั้ง ให้ทำ request ด้วยมือ
curl -v http://192.168.1.10:8080/health

# ถ้า backend ขึ้น firewall ขัง port 8080 ให้เปิด
sudo ufw allow 8080

# หรือบน VPS ที่มี security group ให้เพิ่ม rule ใน AWS/GCP

SSL Certificate ใช้ไม่ได้

# ตรวจสิทธิ์ของไฟล์
sudo ls -la /etc/letsencrypt/live/domain.com/

# ต้องให้ haproxy user สามารถอ่านได้
sudo chown -R haproxy:haproxy /etc/letsencrypt/live/domain.com/

# Reload HAProxy
sudo systemctl reload haproxy

Monitoring และ Logging

ดู Real-time Stats

# ใช้ unix socket เพื่อสอบ stats
echo "show stats" | sudo socat stdio /run/haproxy/admin.sock | head -20

ส่ง Logs ไป Syslog สำหรับวิเคราะห์ต่างหน้า

# ติดตั้ง rsyslog ถ้ายังไม่มี
sudo apt install -y rsyslog

# แก้ /etc/rsyslog.d/99-haproxy.conf
sudo nano /etc/rsyslog.d/99-haproxy.conf

ใส่บรรทัดนี้:

:programname, isequal, "haproxy" /var/log/haproxy/haproxy.log
& ~

บันทึก แล้ว restart rsyslog:

sudo systemctl restart rsyslog

เปรียบเทียบ HAProxy กับ Load Balancer ต่างๆ

ฟีเจอร์ HAProxy Nginx AWS ELB
Connection Handling✅ 1M+ concurrent✅ 100K+Managed (unlimited)
Health Check✅ Built-inPassive only✅ Built-in
Sticky Sessions✅ Cookie-based✅ ip_hash
SSL Termination✅ Full support✅ Full support✅ Full support
ราคาฟรี (Open Source)ฟรี (Open Source)💰 ไม่ฟรี
ComplexityMedium (config ไม่ยุ่ง)Medium (ง่ายกว่า)Low (managed fully)
เหมาะสำหรับHigh-traffic, complex routingGeneral purpose, simpler configFull managed, no config

ต้องการ VPS สำหรับรัน HAProxy + Backend Servers?

AsiaGB มี VPS Linux พร้อม Full Root Access และทำงานเร็วด้วย SSD เหมาะสำหรับตั้ง Load Balancer ขนาด 100K+ concurrent connections โดยไม่มีปัญหา Uptime 99% รับประกัน

ดู VPS Plans