ตั้งค่า HAProxy Load Balancer บน VPS Linux
HAProxy (High Availability Proxy) เป็น load balancer และ proxy ระดับ production ที่ใช้งานกันมากที่สุดในโลก รองรับ throughput สูงมากด้วย resource น้อย มี health check อัจฉริยะ และ stats dashboard ให้ monitor ได้ real-time บทความนี้จะตั้ง HAProxy บน VPS เดี่ยวเพื่อกระจาย HTTP/HTTPS traffic ไปยัง backend server 2-3 เครื่อง
ติดตั้ง HAProxy
sudo apt update
# ติดตั้ง HAProxy version ล่าสุดจาก official PPA
sudo add-apt-repository ppa:vbernat/haproxy-2.8 -y
sudo apt install haproxy -y
# ตรวจสอบ version
haproxy -v
โครงสร้าง Config ของ HAProxy
ไฟล์ config /etc/haproxy/haproxy.cfg แบ่งออกเป็น 4 section หลัก:
- global — ตั้งค่า daemon-level: log, user, limits
- defaults — ค่า default ที่ใช้กับทุก frontend/backend
- frontend — รับ connection จาก client (bind port)
- backend — กลุ่ม server ที่รับ traffic ต่อ
ตั้งค่า HTTP Load Balancer
sudo nano /etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log 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 50000
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
timeout connect 5s
timeout client 30s
timeout server 30s
errorfile 400 /etc/haproxy/errors/400.http
errorfile 503 /etc/haproxy/errors/503.http
# รับ HTTP traffic บน port 80
frontend http_front
bind *:80
default_backend web_servers
# กลุ่ม backend servers
backend web_servers
balance roundrobin
option httpchk GET /health
http-check expect status 200
server web1 192.168.1.10:80 check inter 5s rise 2 fall 3
server web2 192.168.1.11:80 check inter 5s rise 2 fall 3
server web3 192.168.1.12:80 check inter 5s rise 2 fall 3 backup
SSL Termination บน HAProxy
HAProxy รับ HTTPS เองแล้วส่ง HTTP ต่อไปยัง backend — ลดภาระ SSL บน backend server:
# รวม cert และ key ไว้ในไฟล์เดียว (HAProxy ต้องการ)
cat /etc/ssl/certs/example.com.crt /etc/ssl/private/example.com.key \
> /etc/haproxy/certs/example.com.pem
chmod 600 /etc/haproxy/certs/example.com.pem
# เพิ่ม HTTPS frontend ใน haproxy.cfg
frontend https_front
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
# Redirect HTTP ไป HTTPS
http-request redirect scheme https unless { ssl_fc }
# Security headers
http-response set-header Strict-Transport-Security "max-age=31536000"
default_backend web_servers
# ปรับ frontend http_front ให้ redirect ไป HTTPS
frontend http_front
bind *:80
http-request redirect scheme https code 301
Algorithm การกระจาย Traffic
เลือก balance algorithm ให้เหมาะกับ use case:
roundrobin— วนลูปส่งทีละ server เท่าๆ กัน (default, เหมาะสำหรับทั่วไป)leastconn— ส่งไป server ที่มี active connection น้อยที่สุด (เหมาะกับ long-lived connections)source— hash จาก client IP ทำให้ user เดิมไปหา server เดิมทุกครั้ง (เหมาะกับ session sticky)uri— hash จาก URL ทำให้ request เดียวกันไปหา server เดิม (เหมาะกับ caching)
Stats Dashboard
# เพิ่ม stats frontend ใน haproxy.cfg
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:SecurePassword123
stats hide-version
# เปิด port 8404 ใน firewall
sudo ufw allow 8404/tcp
# เข้า dashboard ที่
# http://YOUR_VPS_IP:8404/stats
ssh -L 8404:localhost:8404 user@VPS_IP แล้วเข้าที่ http://localhost:8404/stats
สำหรับการ deploy แบบ high availability ด้วย VPS คุณภาพสูง asiagb.com มีบริการ VPS ในไทยและสิงคโปร์ที่ตั้งค่า HAProxy ได้ทันที รองรับ private networking ระหว่าง VPS ในเครือข่ายเดียวกัน ทำให้ backend server ไม่ต้องเปิด port สาธารณะ ส่วนการตรวจสุขภาพ domain และ DNS ของเซิร์ฟเวอร์ ลองใช้ dnsxray.com เครื่องมือฟรีสำหรับตรวจ SSL, DNS และ HTTP headers
ตรวจสอบว่า HAProxy ทำงานถูกต้อง
# ตรวจสอบ config syntax ก่อน reload ทุกครั้ง
haproxy -c -f /etc/haproxy/haproxy.cfg
# Reload config โดยไม่ drop connection
sudo systemctl reload haproxy
# ดูสถานะ server ทั้งหมดผ่าน socket
echo "show servers state" | sudo socat stdio /run/haproxy/admin.sock
# ทดสอบ load balancing
for i in {1..6}; do curl -s http://YOUR_VPS_IP/ | grep "Server:"; done
option log-health-checks ใน defaults หรือ backend เพื่อ log ทุกครั้งที่ health check fail/pass ช่วย debug ได้ง่ายมากเมื่อ backend server มีปัญหา
แก้ปัญหาที่พบบ่อย
Error: "backend has no server available!" ใน log
Health check fail ทุก backend server ตรวจสอบ endpoint ที่ตั้งใน option httpchk ว่า return 200 จริงไหม:
# ทดสอบ health endpoint จาก haproxy server โดยตรง
curl -sv http://192.168.1.10:80/health
# ดูสถานะ backend server
echo "show servers state web_servers" | sudo socat stdio /run/haproxy/admin.sock
# ถ้า endpoint ไม่มี ให้เปลี่ยนใช้ TCP check แทน
option tcp-check # แทน httpchk
Error: "cannot bind socket" เมื่อ start
Port ที่ต้องการถูกใช้งานแล้วโดย process อื่น (เช่น Nginx หรือ Apache) ต้องหยุด service นั้นก่อน:
# ดูว่า port 80/443 มีใครใช้อยู่
sudo ss -tlnp | grep ':80\|:443'
# หยุด nginx ชั่วคราว
sudo systemctl stop nginx
# ถ้าต้องการรัน HAProxy ร่วมกับ Nginx บนเครื่องเดียว
# ให้ HAProxy ฟัง port 80/443 และ proxy ไปยัง Nginx บน port 8080
Client IP แสดงเป็น IP ของ HAProxy ใน backend log
ต้องเปิด option forwardfor ใน defaults/frontend และ backend app ต้องอ่าน header X-Forwarded-For:
# ตรวจสอบว่าตั้ง forwardfor แล้ว
grep "forwardfor" /etc/haproxy/haproxy.cfg
# ใน Nginx backend ให้ log X-Forwarded-For แทน $remote_addr
log_format main '$http_x_forwarded_for - $remote_user [$time_local] ...';
HAProxy reload ทำให้ connection หลุด
ใช้ systemctl reload haproxy แทน restart HAProxy gracefully reload โดยใช้ socket handoff ทำให้ connection ที่มีอยู่ไม่ถูก drop:
# Graceful reload (ไม่ drop connection)
sudo systemctl reload haproxy
# ห้ามใช้ restart ใน production ยกเว้นจำเป็น
# sudo systemctl restart haproxy ← drop connections ทั้งหมด
คำถามที่พบบ่อย
HAProxy ต่างจาก Nginx upstream load balancing อย่างไร?
Nginx เป็น web server ที่มี load balancing เพิ่มมา HAProxy ถูกออกแบบมาเป็น load balancer โดยเฉพาะ HAProxy มี feature ครบกว่า เช่น per-server weight, advanced health checks, connection draining, ACL routing และ stats socket สำหรับ operation ที่ละเอียด สำหรับ production traffic สูงมาก HAProxy มักทำได้ดีกว่าและ debug ง่ายกว่า
HAProxy รองรับ WebSocket ได้ไหม?
ได้ ต้องใช้ option http-server-close และ backend ต้องรองรับ WebSocket ด้วย HAProxy จะ detect HTTP Upgrade request และส่ง connection ต่อไปยัง backend โดยตรง ไม่ตัด connection กลาง
ถ้า backend server ล่ม HAProxy จัดการอย่างไร?
HAProxy ตรวจ health check ตามที่ตั้งไว้ (inter 5s = ตรวจทุก 5 วินาที) ถ้า fail ตามจำนวน fall ที่กำหนด HAProxy จะ mark server นั้นว่า DOWN และหยุดส่ง traffic ไป เมื่อ server กลับมา pass health check ตามจำนวน rise จะถูก mark กลับเป็น UP และรับ traffic อีกครั้งโดยอัตโนมัติ