คำตอบสั้น ๆ: ตั้ง HAProxy เป็น Load Balancer หน้าเว็บเซิร์ฟเวอร์สองเครื่อง มี Health Check ตัดเครื่องที่ล่มออกอัตโนมัติ หน้า Stats ที่ปลอดภัย Sticky Session และ HTTPS
คู่มือนี้อธิบาย HAProxy ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
HAProxy คือซอฟต์แวร์ Load Balancer แบบโอเพนซอร์สที่รับคำขอจากผู้ใช้แล้วกระจายไปยังเว็บเซิร์ฟเวอร์หลายเครื่อง พร้อมตรวจสุขภาพ (Health Check) ของแต่ละเครื่องอยู่ตลอด ถ้าเครื่องไหนล่ม HAProxy จะหยุดส่งงานไปเครื่องนั้นเองภายในไม่กี่วินาที เหมาะกับเว็บที่โหลดเกินกว่าเครื่องเดียวรับไหว หรือเว็บที่ต้องอัปเดตระบบโดยไม่ปิดหน้าเว็บ
คู่มือนี้ตั้งเครื่อง lb01 ให้รับทราฟฟิกที่ 203.0.113.10 แล้วกระจายไป web01 (10.10.0.11) และ web02 (10.10.0.12) ผ่านเครือข่ายภายใน เมื่อจบคุณจะมี Health Check ที่ใช้งานได้จริง หน้า Stats ที่เปิดได้เฉพาะผู้ดูแล วิธีทำ Sticky Session และทางเลือกให้ HAProxy ถือใบรับรอง HTTPS
สิ่งที่ต้องเตรียม
- Cloud Server สามเครื่องในเครือข่ายภายในเดียวกัน:
lb01ที่มี Public IP และเว็บเซิร์ฟเวอร์สองเครื่องที่ติดตั้ง Nginx และไฟล์เว็บชุดเดียวกัน (ดู ติดตั้ง LEMP) - ระบบปฏิบัติการ Ubuntu 22.04/24.04, Debian 12 หรือ AlmaLinux/Rocky Linux 9 และสิทธิ์
sudo - ข้อมูล Session ของแอปไม่ควรเก็บเป็นไฟล์ในเครื่อง ควรย้ายไป Redis หรือฐานข้อมูลกลาง ไม่เช่นนั้นผู้ใช้จะหลุดล็อกอินเมื่อถูกส่งไปอีกเครื่อง
- DNS ของ
www.example.comชี้มาที่203.0.113.10
ขั้นตอนที่ 1: เตรียมเว็บเซิร์ฟเวอร์ให้มี /health
บน web01 และ web02 เพิ่ม location สำหรับ Health Check และ Header บอกชื่อเครื่องไว้ทดสอบ (เปลี่ยน web01 ให้ตรงกับแต่ละเครื่อง) ใน server block ของ Nginx แล้ว reload
location = /health {
access_log off;
default_type text/plain;
return 200 "ok\n";
}
add_header X-Served-By web01 always;
# ให้ Log ของ Nginx เห็น IP จริงของผู้ใช้แทน IP ของ lb01
set_real_ip_from 10.10.0.5;
real_ip_header X-Forwarded-For;
จากนั้นจำกัดพอร์ต 80 ของเว็บเซิร์ฟเวอร์ให้รับเฉพาะจาก lb01 เช่น sudo ufw allow from 10.10.0.5 to any port 80 proto tcp เพื่อไม่ให้ใครข้าม Load Balancer มาตรงได้
ขั้นตอนที่ 2: ติดตั้ง HAProxy บน lb01
# Ubuntu / Debian
sudo apt update && sudo apt install -y haproxy
# AlmaLinux / Rocky Linux 9
sudo dnf install -y haproxy
haproxy -v
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.orig
Ubuntu 24.04 ได้รุ่น 2.8 ส่วน Ubuntu 22.04 และ AlmaLinux/Rocky 9 ได้รุ่น 2.4 การตั้งค่าในคู่มือนี้ใช้ได้กับทุกรุ่นดังกล่าว บน AlmaLinux/Rocky ไฟล์ตั้งต้นมีตัวอย่าง frontend main ที่พอร์ต 5000 และ backend static, app ให้ลบออก เหลือไว้เฉพาะ global และ defaults
ขั้นตอนที่ 3: เขียน frontend และ backend พร้อม Health Check
เพิ่มท้ายไฟล์ /etc/haproxy/haproxy.cfg โดย frontend คือฝั่งที่รับคำขอ ส่วน backend คือกลุ่มเซิร์ฟเวอร์ที่รับงานต่อ
frontend web_front
bind *:80
mode http
option forwardfor
default_backend web_servers
backend web_servers
mode http
balance roundrobin
option httpchk
http-check send meth GET uri /health ver HTTP/1.1 hdr Host www.example.com
http-check expect status 200
default-server inter 3s fall 3 rise 2
server web01 10.10.0.11:80 check
server web02 10.10.0.12:80 check
balance roundrobinส่งงานสลับกันทีละเครื่อง ถ้าคำขอใช้เวลานานไม่เท่ากัน เช่น รายงานหรืออัปโหลดไฟล์ ให้ใช้leastconnซึ่งส่งไปเครื่องที่มีการเชื่อมต่อค้างน้อยที่สุดinter 3s fall 3 rise 2ตรวจทุก 3 วินาที พลาด 3 ครั้งติดถือว่าล่ม ผ่าน 2 ครั้งติดจึงรับกลับoption forwardforส่ง IP จริงของผู้ใช้ไปใน HeaderX-Forwarded-For
ขั้นตอนที่ 4: ตรวจไฟล์ เปิด Firewall และ reload
ตรวจไวยากรณ์ก่อนทุกครั้ง ถ้าถูกต้องจะขึ้น Configuration file is valid แล้วจึงเปิดบริการ การ reload ไม่ตัดการเชื่อมต่อที่กำลังใช้งานอยู่
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl enable --now haproxy
sudo systemctl reload haproxy
# Ubuntu / Debian
sudo ufw allow 80,443/tcp
# AlmaLinux / Rocky Linux 9
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload
ทดสอบจากเครื่องของคุณ แล้วลองหยุด Nginx บน web02 ภายในประมาณ 9 วินาทีทุกคำขอจะไปที่ web01 และ journalctl -u haproxy จะบันทึกว่า web02 เป็น DOWN
for i in 1 2 3 4; do curl -s -o /dev/null -D - http://203.0.113.10/ | grep -i x-served-by; done