Load Balancer คืออะไร ตั้งค่าบน VPS อย่างไร

เมื่อเว็บไซต์ของคุณเริ่มมีผู้เข้าชมมากขึ้น เซิร์ฟเวอร์ตัวเดียวอาจไม่เพียงพอรับ 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 ทีละตัว
ScaleVertical (ขยาย 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-LBLoad Balancer (Nginx)10.0.0.1
VPS-B1Backend Server 1 (Web App)10.0.0.2
VPS-B2Backend 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.com

Certbot จะแก้ไข 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 ทั้งหมด →