ตั้งค่า Nginx เป็น Load Balancer บน VPS

เมื่อ Traffic เว็บเพิ่มขึ้นจนเซิร์ฟเวอร์เดียวรับไม่ไหว Load Balancer คือคำตอบ Nginx รองรับฟีเจอร์ Load Balancing แบบ Production-grade ในตัว ไม่ต้องใช้ซอฟต์แวร์เพิ่มเติม บทความนี้จะแนะนำการตั้งค่า Nginx เป็น Load Balancer บน VPS Ubuntu เพื่อกระจาย Request ไปยัง Backend Server หลายเครื่อง

Load Balancing ทำงานอย่างไร

Load Balancer รับ Request จาก Client แล้วส่งต่อไปยัง Backend Server ที่เหมาะสม ช่วยให้ระบบรับ Traffic ได้มากขึ้น ป้องกัน Single Point of Failure และทำ Zero-downtime Deploy ได้

Round-Robin

ส่ง Request สลับกันทุก Server ทีละเที่ยว เหมาะกับ Backend ที่ Spec เท่ากัน

Least Connection

ส่ง Request ไปยัง Server ที่มี Active Connection น้อยที่สุด เหมาะกับ Request ที่ใช้เวลาต่างกัน

IP Hash

ผู้ใช้ IP เดิมถูกส่งไปยัง Backend เดิมเสมอ เหมาะกับแอปที่ต้องการ Session Sticky

สถาปัตยกรรมที่จะตั้งค่า

ในตัวอย่างนี้ VPS เครื่อง Load Balancer (IP: 10.0.0.1) รับ Traffic Port 80/443 แล้วกระจายไปยัง Backend 2 เครื่อง (10.0.0.2 และ 10.0.0.3) ที่รันแอป Port 8080

ติดตั้ง Nginx บน VPS Load Balancer

sudo apt update && sudo apt install -y nginx sudo systemctl enable nginx

ตั้งค่า upstream และ Load Balancing

สร้างไฟล์ Config ใหม่:

sudo nano /etc/nginx/sites-available/loadbalancer

ใส่ Config ต่อไปนี้ (Round-Robin):

# กำหนดกลุ่ม Backend Server upstream backend_pool { server 10.0.0.2:8080; server 10.0.0.3:8080; # keepalive connections เพิ่ม Performance keepalive 32; } server { listen 80; server_name yourdomain.com; location / { proxy_pass http://backend_pool; proxy_http_version 1.1; proxy_set_header Connection ""; 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; } }

เปลี่ยนเป็น Least Connection

upstream backend_pool { least_conn; server 10.0.0.2:8080; server 10.0.0.3:8080; }

เปลี่ยนเป็น IP Hash (Session Sticky)

upstream backend_pool { ip_hash; server 10.0.0.2:8080; server 10.0.0.3:8080; }

ตั้งค่า Weight สำหรับ Server Spec ต่างกัน

upstream backend_pool { server 10.0.0.2:8080 weight=3; # รับ Traffic 3 ส่วน server 10.0.0.3:8080 weight=1; # รับ Traffic 1 ส่วน }

เปิด Config และทดสอบ

sudo ln -s /etc/nginx/sites-available/loadbalancer /etc/nginx/sites-enabled/ sudo nginx -t # ตรวจ syntax sudo systemctl reload nginx

เข้าใจ Upstream Module และ Directive ที่สำคัญ

ก่อนจะตั้งค่า Load Balancer ให้ทำงานได้ดีใน Production ควรทำความเข้าใจ Directive หลักของ Nginx Upstream Module ก่อน เพื่อให้สามารถปรับแต่งพฤติกรรมให้เหมาะกับ Workload จริงของแต่ละระบบ

ตัวอย่างการใช้ Directive รวมกันแบบ Production-ready สำหรับระบบที่ต้องการ Failover อัตโนมัติ:

upstream backend_pool { server 10.0.0.2:8080 weight=2 max_fails=3 fail_timeout=30s; server 10.0.0.3:8080 weight=2 max_fails=3 fail_timeout=30s; server 10.0.0.4:8080 backup; # ใช้เฉพาะเมื่อ 2 เครื่องหลัก down keepalive 32; }

วิธีทดสอบ Load Balancing ให้มั่นใจก่อน Production

หลังตั้งค่าเสร็จควรทดสอบให้แน่ใจว่า Load Balancer กระจาย Traffic ได้จริง และ Health Check ทำงานถูกต้องก่อนจะเปิดให้ Traffic จริงเข้ามา

ทดสอบด้วย curl

ส่ง Request หลายครั้งแล้วดูว่า Response มาจาก Backend ต่างกันหรือไม่ (Backend ต้องส่งชื่อตัวเองกลับมาใน Header หรือ Body เพื่อให้ตรวจสอบได้)

# ส่ง 6 Request ดู Distribution for i in {1..6}; do curl -s http://yourdomain.com/api/ping | grep '"server"' done

ทดสอบด้วย wrk (Benchmark)

# ต้องติดตั้ง wrk ก่อน: apt install wrk wrk -t4 -c100 -d30s http://yourdomain.com/ # ดูผลที่ได้: Requests/sec, Latency avg/max, Transfer/sec

จำลองการ Fail ของ Backend

# หยุด Backend เครื่องที่ 2 ชั่วคราว ssh [email protected] 'sudo systemctl stop myapp' # ส่ง Request มาที่ Load Balancer — ควรยัง Response ปกติ curl -v http://yourdomain.com/ # เปิด Backend กลับ ssh [email protected] 'sudo systemctl start myapp'

ถ้า Load Balancer ตั้งค่าถูกต้อง เมื่อ Backend เครื่องหนึ่ง Down ระบบยังต้องตอบสนองได้ปกติโดยส่ง Request ไปยัง Backend ที่เหลือ นี่คือการ Verify High Availability แบบพื้นฐานที่ต้องทำก่อน Go Live ทุกครั้ง

การวางแผนสถาปัตยกรรม Network สำหรับ Load Balancer

ก่อนเริ่มตั้งค่า Nginx ควรวางแผนสถาปัตยกรรม Network ให้รัดกุมก่อน เพราะการออกแบบที่ดีตั้งแต่แรกช่วยลดปัญหาด้าน Security ประสิทธิภาพ และการขยายระบบในอนาคต

รูปแบบที่แนะนำสำหรับ VPS หลายเครื่อง

# ตั้งค่า Firewall บน Backend VPS (อนุญาตเฉพาะ LB) sudo ufw allow from 10.0.0.1 to any port 8080 sudo ufw deny 8080 # ปิด Public access ก่อน แล้วค่อย allow เฉพาะ LB sudo ufw enable

การแยก Network Traffic ระหว่าง Public (Load Balancer) กับ Private (Backend) เป็นแนวปฏิบัติด้าน Security ที่ควรทำตั้งแต่วันแรก การแก้ไขภายหลังเมื่อระบบมี Traffic แล้วทำได้ยากและเสี่ยงกว่า

การติดตามประสิทธิภาพและ Logging

เมื่อ Load Balancer ทำงานบน Production ควรติดตาม Metrics เหล่านี้อย่างสม่ำเสมอเพื่อให้รู้ว่าระบบทำงานได้ดีแค่ไหนและมีปัญหาที่ไหนก่อนที่ User จะรายงาน

Metrics ที่ต้องติดตาม

ตั้งค่า Custom Log Format สำหรับ Load Balancer

# เพิ่มใน http{} block ใน nginx.conf log_format lb_log '$remote_addr - $upstream_addr [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'rt=$request_time uct=$upstream_connect_time ' 'uht=$upstream_header_time urt=$upstream_response_time'; access_log /var/log/nginx/lb_access.log lb_log; error_log /var/log/nginx/lb_error.log warn;

ฟิลด์ $upstream_addr บอกว่า Request นั้นถูกส่งไปยัง Backend เครื่องไหน ช่วยให้ Debug ปัญหาเฉพาะ Backend ได้ง่ายขึ้นมาก และ $upstream_response_time บอก Latency จริงของ Backend นั้นๆ

เพิ่ม Timeout และ Buffer สำหรับ Production

การปรับค่า Timeout และ Buffer ช่วยให้ Load Balancer รับมือกับ Backend ที่ตอบสนองช้าหรือ Response ขนาดใหญ่ได้ดีขึ้น ควรตั้งค่าเหล่านี้ในส่วน location / หรือในบล็อก server หลัก

server { listen 80; server_name yourdomain.com; location / { proxy_pass http://backend_pool; proxy_http_version 1.1; proxy_set_header Connection ""; 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; # Timeout settings proxy_connect_timeout 5s; proxy_send_timeout 60s; proxy_read_timeout 60s; # Buffer settings — ปรับตามขนาด Response proxy_buffering on; proxy_buffer_size 16k; proxy_buffers 8 16k; proxy_busy_buffers_size 32k; } }

หากแอปส่ง Response ขนาดเล็กและต้องการ Latency ต่ำ (เช่น API) สามารถปิด Buffering ได้ด้วย proxy_buffering off; แต่จะเพิ่มภาระให้ Worker Process มากขึ้น

ตั้งค่า SSL/TLS Termination บน Load Balancer

วิธีที่นิยมที่สุดสำหรับ Production คือให้ Load Balancer รับ HTTPS จาก Client แล้วส่งต่อเป็น HTTP ภายใน (SSL Termination) — Backend ไม่ต้องจัดการ Certificate เอง ลด Overhead และทำให้ดูแลง่ายขึ้น

# ใช้ Certbot สร้าง Certificate ก่อน sudo certbot --nginx -d yourdomain.com # จากนั้น Config HTTPS block server { listen 443 ssl http2; server_name yourdomain.com; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; location / { proxy_pass http://backend_pool; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto https; } } # Redirect HTTP → HTTPS server { listen 80; server_name yourdomain.com; return 301 https://$host$request_uri; }

ตั้งค่า Rate Limiting เพื่อป้องกัน DDoS

Load Balancer เป็นจุดรับ Traffic ทั้งหมด จึงเหมาะมากสำหรับตั้งค่า Rate Limiting เพื่อกัน Request ที่มากเกินไปจาก IP เดียวกัน ป้องกัน DDoS เบื้องต้นและ Brute-force Attack

# กำหนด Zone ใน http{} block (nginx.conf) http { limit_req_zone $binary_remote_addr zone=api_limit:10m rate=30r/m; ... } # ใช้งานใน location block location /api/ { limit_req zone=api_limit burst=10 nodelay; limit_req_status 429; proxy_pass http://backend_pool; } location / { limit_req zone=api_limit burst=50 nodelay; proxy_pass http://backend_pool; }

ค่า rate=30r/m หมายถึงอนุญาต 30 Request ต่อนาทีต่อ IP ส่วน burst=10 คือจำนวน Request ที่รับได้เกิน Rate ชั่วคราวก่อน Return 429 Too Many Requests

ค่า เหมาะกับ หมายเหตุ
10r/s API ทั่วไป เข้มงวดปานกลาง
1r/s Login endpoint เข้มงวด กัน Brute-force
100r/s Static files หลวมสำหรับไฟล์สาธารณะ

ตั้งค่า Health Check (Passive)

Nginx Open Source รองรับ Passive Health Check โดยอัตโนมัติ — ถ้า Backend ตอบสนองด้วย Error ติดต่อกัน Nginx จะ Remove ออกชั่วคราว:

upstream backend_pool { server 10.0.0.2:8080 max_fails=3 fail_timeout=30s; server 10.0.0.3:8080 max_fails=3 fail_timeout=30s; }

Nginx Plus (Commercial): รองรับ Active Health Check (ตรวจสอบ Backend ทุก N วินาที) ถ้าต้องการ Active Health Check แบบ Open Source ให้ใช้ HAProxy หรือ Nginx + Lua Module แทน

สรุปและขั้นตอนต่อไปหลังจาก Load Balancer ทำงาน

เมื่อ Nginx Load Balancer ทำงานได้แล้วบน VPS ขั้นตอนต่อไปที่ควรทำเพื่อให้ระบบพร้อมสำหรับ Production เต็มรูปแบบมีดังนี้

Nginx Load Balancer บน VPS เป็นรากฐานสำคัญของระบบ High Availability ที่คุ้มค่ามาก เพราะซอฟต์แวร์เป็น Open Source ไม่มีค่าลิขสิทธิ์ และรองรับ Traffic ได้สูงมากด้วย Hardware ราคาไม่แพง VPS AsiaGB ที่มี Full Root Access ช่วยให้ตั้งค่า Nginx ได้เต็มรูปแบบโดยไม่มีข้อจำกัดจาก Hosting Provider

ตรวจสอบสถานะ Load Balancer

sudo nginx -t && sudo systemctl status nginx # ดู Access Log แบบ Real-time sudo tail -f /var/log/nginx/access.log

VPS สำหรับ High Traffic มีพร้อมที่ AsiaGB

VPS AsiaGB รองรับ Linux Ubuntu/Debian พร้อม Root Access ตั้งค่า Nginx Load Balancer ได้เต็มรูปแบบ เริ่มต้น 500 บาท/เดือน

ดูแพ็กเกจ VPS