
เมื่อเว็บไซต์ของคุณเริ่มมีผู้เข้าชมมากขึ้น เซิร์ฟเวอร์ตัวเดียวอาจไม่เพียงพอรับ Traffic ได้ทั้งหมด และถ้าเซิร์ฟเวอร์นั้นล่ม เว็บไซต์ก็จะล่มไปด้วย Load Balancer คือทางออกที่ใช้กันในระดับ Production — กระจาย Traffic ไปยังหลายเซิร์ฟเวอร์อัตโนมัติ เพื่อให้บริการได้ต่อเนื่องแม้เซิร์ฟเวอร์ตัวใดตัวหนึ่งมีปัญหา
บทความนี้อธิบายว่า Load Balancer คืออะไร ทำงานอย่างไร เลือก Algorithm ไหนดี และวิธีตั้งค่า Nginx เป็น Load Balancer บน VPS Ubuntu ตั้งแต่ต้นจนจบ
สิ่งที่ต้องมีก่อน: VPS Ubuntu 20.04/22.04 อย่างน้อย 2 ตัว (1 ตัวเป็น Load Balancer + อย่างน้อย 2 ตัวเป็น Backend), SSH Access, Nginx ติดตั้งแล้วบนทุก VPS
Load Balancer คืออะไร
Load Balancer คืออุปกรณ์หรือซอฟต์แวร์ที่ทำหน้าที่เป็น ตัวกลางรับ Traffic จากผู้ใช้ แล้วกระจายไปยัง Backend Servers หลายตัวตาม Algorithm ที่กำหนด แทนที่ผู้ใช้จะเชื่อมต่อตรงกับเซิร์ฟเวอร์เดียว ทุก Request จะผ่าน Load Balancer ก่อนเสมอ
| หัวข้อ | ไม่มี Load Balancer | มี Load Balancer |
|---|---|---|
| Single Point of Failure | ใช่ — เซิร์ฟเวอร์ล่ม = เว็บล่ม | ไม่ — เซิร์ฟเวอร์ 1 ล่ม ส่งต่อไปอีกตัว |
| รองรับ Traffic สูง | จำกัดที่ Spec เซิร์ฟเวอร์เดียว | กระจายได้หลายเซิร์ฟเวอร์ |
| Maintenance | ต้องปิดเว็บ | ถอด Server ออก Deploy ทีละตัว |
| Scale | Vertical (ขยาย Spec เดียว) | Horizontal (เพิ่มเซิร์ฟเวอร์ได้เรื่อยๆ) |
Load Balancing Algorithm — มีกี่แบบ
วิธีที่ Load Balancer ตัดสินใจว่าจะส่ง Request ไปที่ Server ไหน เรียกว่า Algorithm แต่ละแบบเหมาะกับสถานการณ์ต่างกัน:
1. Round Robin (ค่าเริ่มต้น)
ส่ง Request วนไปตามลำดับ — เซิร์ฟเวอร์ A → B → C → A → B → C → ... เหมาะเมื่อทุกเซิร์ฟเวอร์มี Spec ใกล้เคียงกัน และแต่ละ Request ใช้ทรัพยากรพอๆ กัน
2. Least Connections
ส่ง Request ไปยังเซิร์ฟเวอร์ที่มี Active Connections น้อยที่สุดในขณะนั้น เหมาะกับงานที่ใช้เวลาประมวลผลต่างกันมาก เช่น API ที่บาง Request ใช้เวลานาน บาง Request เร็ว
3. IP Hash
ใช้ IP Address ของผู้ใช้คำนวณว่าจะส่งไปเซิร์ฟเวอร์ไหน ผู้ใช้ IP เดิมจะถูกส่งไปเซิร์ฟเวอร์เดิมเสมอ (Session Persistence) เหมาะกับ Application ที่เก็บ Session บน Server Memory โดยไม่ใช้ Redis หรือ DB ร่วมกัน
4. Weighted Round Robin
Round Robin แบบกำหนด Weight — เซิร์ฟเวอร์ที่มี Spec สูงกว่าได้รับ Traffic มากกว่า เช่น Server A (weight=3) รับ 3 ใน 4 requests, Server B (weight=1) รับ 1 ใน 4 requests
ตั้งค่า Nginx Load Balancer บน VPS Ubuntu
Nginx รองรับ Load Balancing แบบ Built-in ไม่ต้องติดตั้งซอฟต์แวร์เพิ่ม ตัวอย่างนี้ใช้ VPS 3 ตัว:
| ตัว | บทบาท | IP ตัวอย่าง |
|---|---|---|
| VPS-LB | Load Balancer (Nginx) | 10.0.0.1 |
| VPS-B1 | Backend Server 1 (Web App) | 10.0.0.2 |
| VPS-B2 | Backend Server 2 (Web App) | 10.0.0.3 |
ขั้นที่ 1 — ติดตั้ง Nginx บน Load Balancer
SSH เข้า VPS-LB แล้วติดตั้ง Nginx:
sudo apt update && sudo apt install nginx -y sudo systemctl enable nginx sudo systemctl start nginx
ขั้นที่ 2 — สร้าง Upstream Block
สร้างไฟล์ Config สำหรับ Load Balancer:
sudo nano /etc/nginx/sites-available/load-balancer
วางเนื้อหานี้ลงในไฟล์ (Round Robin เป็นค่าเริ่มต้น):
upstream backend_pool {
# Round Robin (default) — ลบ comment เพื่อเปลี่ยน algorithm
# least_conn; ← Least Connections
# ip_hash; ← IP Hash (Session Persistence)
server 10.0.0.2:80;
server 10.0.0.3:80;
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location / {
proxy_pass http://backend_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}proxy_set_header คืออะไร? Header เหล่านี้ส่ง IP จริงของผู้ใช้ไปให้ Backend Server ด้วย ถ้าไม่ใส่ Backend จะเห็นแค่ IP ของ Load Balancer แทน
ขั้นที่ 3 — เปิดใช้งาน Config
# สร้าง symlink เพื่อเปิดใช้งาน sudo ln -s /etc/nginx/sites-available/load-balancer /etc/nginx/sites-enabled/ # ตรวจ syntax ก่อน reload sudo nginx -t # Reload Nginx sudo systemctl reload nginx
ขั้นที่ 4 — ใช้ Weighted Round Robin
ถ้า VPS-B1 มี Spec สูงกว่า VPS-B2 ให้กำหนด Weight เพื่อให้รับ Traffic มากกว่า:
upstream backend_pool {
server 10.0.0.2:80 weight=3; # รับ 3 ใน 4 requests
server 10.0.0.3:80 weight=1; # รับ 1 ใน 4 requests
}ขั้นที่ 5 — ตั้งค่า Health Checks
Nginx สามารถตรวจสอบว่า Backend Server ยังทำงานอยู่หรือไม่ ถ้าเซิร์ฟเวอร์ตัวใดตอบไม่ได้ จะหยุดส่ง Traffic ไปที่นั่นชั่วคราว:
upstream backend_pool {
server 10.0.0.2:80 max_fails=3 fail_timeout=30s;
server 10.0.0.3:80 max_fails=3 fail_timeout=30s;
}| ตัวเลือก | ความหมาย |
|---|---|
| max_fails=3 | ถ้า Health Check ล้มเหลว 3 ครั้งติดกัน ถือว่า Server นั้นเสีย |
| fail_timeout=30s | เวลา 30 วินาทีที่จะไม่ส่ง Traffic ไปก่อน แล้วลองใหม่ |
เพิ่ม Passive Health Check ให้ละเอียดขึ้นด้วย proxy_next_upstream:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://backend_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# ถ้า Backend ตอบ error ให้ลอง Backend ตัวถัดไปทันที
proxy_next_upstream error timeout http_502 http_503 http_504;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
}ขั้นที่ 6 — เพิ่ม SSL ให้ Load Balancer (HTTPS)
ผู้ใช้เชื่อมต่อกับ Load Balancer เท่านั้น ดังนั้นติดตั้ง SSL ที่ Load Balancer เพียงตัวเดียว ส่วน Backend ใช้ HTTP ในเครือข่าย Private ได้:
# ติดตั้ง Certbot สำหรับ Let's Encrypt
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.comCertbot จะแก้ไข Config ของ Nginx อัตโนมัติให้รองรับ HTTPS และตั้งค่า Auto-Renewal ให้ด้วย
SSL Termination: แนวทางนี้เรียกว่า SSL Termination ที่ Load Balancer — Traffic ระหว่าง LB กับ Backend เป็น HTTP ธรรมดา เหมาะเมื่อ Backend อยู่ใน Private Network เดียวกัน ถ้า Backend อยู่ต่าง Data Center ควรใช้ HTTPS ตลอดเส้นทาง (End-to-End SSL)
ขั้นที่ 7 — ทดสอบการกระจาย Traffic
ให้ Backend Server แต่ละตัวแสดงค่า Hostname ที่ต่างกัน เพื่อตรวจสอบว่า Load Balancer กระจาย Traffic ได้จริง:
# บน VPS-B1 — ตรวจสอบ IP จริง curl -s http://yourdomain.com/ # ลอง curl หลายครั้งเพื่อดูว่า Response มาจากต่าง Server for i in {1..6}; do curl -s http://yourdomain.com/hostname.php; echo; done
สร้าง hostname.php เล็กๆ บน Backend แต่ละตัวเพื่อตรวจสอบ:
# บน VPS-B1 echo '<?php echo "Response from: " . gethostname(); ?>' > /var/www/html/hostname.php # บน VPS-B2 echo '<?php echo "Response from: " . gethostname(); ?>' > /var/www/html/hostname.php
ผลที่ได้ควรสลับระหว่าง Response from: vps-b1 และ Response from: vps-b2 ตาม Round Robin
ทดสอบ Failover — ปิด Backend ตัวหนึ่ง
ทดสอบว่าเมื่อ Backend ตัวหนึ่งล่ม เว็บยังทำงานได้หรือไม่:
# ปิด Nginx บน VPS-B1 เพื่อจำลองเซิร์ฟเวอร์ล่ม sudo systemctl stop nginx # ทดสอบจากเครื่องส่วนตัว — ควรยังตอบสนองได้จาก VPS-B2 curl http://yourdomain.com/
ผลที่ควรได้: เว็บยังทำงานได้ต่อเนื่องจาก VPS-B2 Nginx บน Load Balancer จะตรวจพบว่า VPS-B1 ไม่ตอบสนอง และหยุดส่ง Traffic ไปที่นั่นอัตโนมัติ (ตาม max_fails ที่ตั้งไว้)
เพิ่ม Server เข้า Pool โดยไม่ Restart
เมื่อต้องการเพิ่ม Backend Server ใหม่ แก้ Config แล้ว Reload Nginx — โดยไม่ต้อง Restart เซิร์ฟเวอร์:
# เพิ่ม VPS-B3 เข้า Pool upstream backend_pool { server 10.0.0.2:80 max_fails=3 fail_timeout=30s; server 10.0.0.3:80 max_fails=3 fail_timeout=30s; server 10.0.0.4:80 max_fails=3 fail_timeout=30s; # ← เพิ่มใหม่ } # Reload โดยไม่มี Downtime sudo nginx -t && sudo systemctl reload nginx
ดู Log และ Monitor
ตรวจสอบว่า Load Balancer กำลังส่ง Traffic ไปไหน และมี Error อะไรบ้าง:
# ดู Access Log แบบ Real-time sudo tail -f /var/log/nginx/access.log # ดู Error Log sudo tail -f /var/log/nginx/error.log # ดูสถานะ Active Connections sudo nginx -s status 2>/dev/null || curl http://localhost/nginx_status
ก้าวต่อไป: เมื่อ Load Balancer ทำงานได้แล้ว ขั้นต่อไปคือตั้งค่า Shared Session (Redis) และ Shared File Storage (NFS หรือ Object Storage) เพื่อให้ Backend ทุกตัวใช้ข้อมูลเดียวกัน และพิจารณาใช้ Keepalived เพื่อทำให้ Load Balancer เองมี High Availability ด้วย
ตั้งค่า Nginx Status Module สำหรับ Monitor แบบ Real-time
Nginx มี stub_status Module ในตัวสำหรับดูสถิติ Connection แบบ Real-time ซึ่งช่วยให้รู้ว่า Load Balancer กำลังจัดการ Traffic หนักแค่ไหนในขณะนั้น
# เปิดใช้งาน stub_status ใน server block ของ Load Balancer server { listen 80; server_name yourdomain.com; location /nginx_status { stub_status on; allow 127.0.0.1; # อนุญาตเฉพาะ localhost allow 10.0.0.0/24; # อนุญาต Private Network deny all; # บล็อกทุก IP อื่น } location / { proxy_pass http://backend_pool; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
หลัง Reload Nginx แล้ว รัน curl เพื่อดู Status:
curl http://localhost/nginx_status
ผลลัพธ์ที่ได้จะมีลักษณะดังนี้:
Active connections: 45 server accepts handled requests 1024 1024 3891 Reading: 0 Writing: 3 Waiting: 42
| Field | ความหมาย |
|---|---|
| Active connections | จำนวน Connection ที่กำลัง Active ทั้งหมดในขณะนั้น |
| accepts | จำนวน Connection ที่รับมาทั้งหมดตั้งแต่เริ่ม Nginx |
| handled | จำนวน Connection ที่ประมวลผลสำเร็จ (ควรเท่ากับ accepts) |
| Reading | กำลังอ่าน Request Header |
| Writing | กำลังส่ง Response กลับ Client |
| Waiting | รอ Request ใหม่บน Keep-alive Connection |
การแก้ปัญหา Session บน Load Balancer ด้วย Redis Shared Session
ปัญหาที่พบบ่อยที่สุดเมื่อใช้ Load Balancer กับ Web Application คือ Session ไม่สอดคล้อง ผู้ใช้ Login แล้วถูก Route ไป Backend ตัวอื่นที่ไม่มี Session ของเขา — ทำให้ถูก Logout อัตโนมัติ วิธีแก้ที่ถูกต้องคือใช้ Redis เป็น Session Storage กลาง ที่ Backend ทุกตัวสามารถอ่าน-เขียนร่วมกันได้
ติดตั้ง Redis บน VPS แยกต่างหาก (แนะนำ) หรือบน Load Balancer
sudo apt install redis-server -y sudo systemctl enable redis-server # เปิดให้ Backend Server เชื่อมต่อได้ (แก้ bind ใน /etc/redis/redis.conf) sudo nano /etc/redis/redis.conf # แก้บรรทัด: bind 127.0.0.1 → bind 127.0.0.1 10.0.0.1 # แล้ว restart Redis sudo systemctl restart redis-server
ตั้งค่า PHP ให้ใช้ Redis Session (บน Backend ทุกตัว)
# แก้ /etc/php/8.x/apache2/php.ini หรือ /etc/php/8.x/fpm/php.ini
session.save_handler = redis
session.save_path = "tcp://10.0.0.1:6379?auth=yourpassword"ผลที่ได้: ผู้ใช้ Login ไม่ว่าจะถูก Route ไป VPS-B1 หรือ VPS-B2 ก็อ่าน Session จาก Redis ตัวเดียวกัน — ไม่มีปัญหา Logout กลางคัน ไม่ต้องใช้ IP Hash ซึ่งจะทำให้กระจาย Traffic ไม่สม่ำเสมอ
Load Balancer vs Reverse Proxy — ต่างกันอย่างไร
หลายคนสับสนระหว่าง Load Balancer กับ Reverse Proxy ทั้งสองใช้ Nginx ได้และมีรูปแบบ Config คล้ายกัน แต่มีวัตถุประสงค์ต่างกัน:
| คุณสมบัติ | Reverse Proxy | Load Balancer |
|---|---|---|
| วัตถุประสงค์หลัก | รับ Request แทน Backend ตัวเดียว | กระจาย Request ไปหลาย Backend |
| Backend จำนวน | 1 ตัว (ส่วนใหญ่) | 2+ ตัว (เป็นหลัก) |
| Failover | ไม่มี — Backend ล่ม = เว็บล่ม | มี — เปลี่ยนไปใช้ Backend ที่ดี |
| ประโยชน์หลัก | SSL, Caching, Compression | High Availability, Scalability |
| Config Nginx | proxy_pass http://127.0.0.1:3000 | upstream block + proxy_pass |
ในทางปฏิบัติ Load Balancer ใน Nginx คือ Reverse Proxy ที่มี Upstream Pool — ทั้งสองเป็นฟีเจอร์ของ Nginx ตัวเดียวกัน ความแตกต่างอยู่ที่จำนวน Backend และ Algorithm ที่ใช้ในการส่งต่อ Request
ค่าใช้จ่ายและ Architecture ที่แนะนำสำหรับ VPS ไทย-สิงคโปร์
AsiaGB ให้บริการ VPS ทั้งในไทยและสิงคโปร์ ซึ่งเหมาะสำหรับสร้าง Load Balancer Architecture แบบ Multi-Region เพื่อรองรับผู้ใช้ทั้งในไทยและต่างประเทศ:
| บทบาท | แนะนำ | ราคาเริ่มต้น |
|---|---|---|
| Load Balancer (LB) | VPS ไทย Starter — ทราฟฟิกต่ำ CPU เพียงพอ | 500 บาท/เดือน |
| Backend 1 (TH) | VPS ไทย — latency ต่ำสำหรับผู้ใช้ในไทย | 500 บาท/เดือน |
| Backend 2 (SG) | VPS สิงคโปร์ — ครอบคลุมผู้ใช้ SEA / Global | 500 บาท/เดือน |
หมายเหตุ Multi-Region: ถ้า Backend อยู่คนละ Data Center (ไทยกับสิงคโปร์) Session และ Database ต้องซิงก์กันผ่าน Network ซึ่งมี Latency หลัก ms ควรใช้ Redis Cluster หรือ MySQL Replication และพิจารณา Algorithm แบบ IP Hash เพื่อให้ผู้ใช้คนเดิมไปที่ Backend เดิมเสมอ
ต้องการ VPS สำหรับ Load Balancer?
AsiaGB มี VPS ไทย และ สิงคโปร์ พร้อม Full Root Access เริ่มต้น 500 บาท/เดือน เพิ่มเซิร์ฟเวอร์เข้า Pool ได้ทุกเมื่อ
ดู VPS ทั้งหมด →