เมื่อแอปพลิเคชันของคุณเติบโตและรับภาระงานสูงมากขึ้น ปัญหาที่พบบ่อยคือ 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 เท่านั้น
- Connection handling — HAProxy สามารถรับ connection พร้อมกัน 1,000,000+ แม้บนเซิร์ฟเวอร์ธรรมชาติ ด้วยเทคนิค epoll
- Health Check ที่ฉลาด — HAProxy ส่ง HTTP/TCP request ไปทดสอบ backend servers อัตโนมัติ ถ้า server ไม่ตอบให้หยิบออกจากกลุ่มชั่วคราว
- Sticky Sessions — ผูกมัด session ของลูกค้าเดียวกันไปยัง backend server เดียวกันตลอด
- SSL Termination — ถอด HTTPS ที่ client ส่งมา สื่อสารไปยัง backend เป็น HTTP ธรรมดา ออกแรงประมวลผล CPU ลง
- Logging ที่ละเอียด — บันทึก request ทั้งหมด พร้อม timing ละเอียดเพื่อวิเคราะห์ performance
สิ่งที่ต้องมีก่อนเริ่ม
- VPS Ubuntu 20.04+ หรือ Debian ที่ใช้ systemd ติดตั้งแล้ว
- Backend servers อย่างน้อย 2-3 ตัว (ที่ต้องการ load balance) โดยแต่ละตัวรัน web service อยู่แล้ว
- Domain ชี้มาที่ IP ของ HAProxy server ผ่าน DNS A Record
- Port 80 และ 443 เปิดใน Firewall และไม่มี service อื่นใช้ port เหล่านี้
- ความสามารถพื้นฐานในการแก้ไฟล์ config ผ่าน terminal editor (nano/vim)
ขั้นที่ 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
สิ่งสำคัญที่ต้องแก้ไข:
- แทนที่
domain.comด้วยโดเมนจริงของคุณ - แทนที่ IP address 192.168.1.10, 192.168.1.11, 192.168.1.12 ด้วย IP ของ backend servers จริง
- ถ้า backend ใช้ port แตกต่างกัน ให้แก้ port 8080 เป็นของจริง
ขั้นที่ 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-in | Passive only | ✅ Built-in |
| Sticky Sessions | ✅ Cookie-based | ✅ ip_hash | ✅ |
| SSL Termination | ✅ Full support | ✅ Full support | ✅ Full support |
| ราคา | ฟรี (Open Source) | ฟรี (Open Source) | 💰 ไม่ฟรี |
| Complexity | Medium (config ไม่ยุ่ง) | Medium (ง่ายกว่า) | Low (managed fully) |
| เหมาะสำหรับ | High-traffic, complex routing | General purpose, simpler config | Full managed, no config |
ต้องการ VPS สำหรับรัน HAProxy + Backend Servers?
AsiaGB มี VPS Linux พร้อม Full Root Access และทำงานเร็วด้วย SSD เหมาะสำหรับตั้ง Load Balancer ขนาด 100K+ concurrent connections โดยไม่มีปัญหา Uptime 99% รับประกัน
ดู VPS Plans