Load Balancer บน DigitalOcean: กระจายโหลดหลาย Droplet, Health Check, SSL และ Sticky Session
อธิบาย Load Balancer ของ DigitalOcean ตั้งแต่แนวคิด การสร้าง กฎ forwarding, health check, SSL termination, sticky sessions, ข้อจำกัดของ session และสถาปัตยกรรมเว็บที่ scale ได้โดยไม่ล่มตอนอัปเดต
Load Balancer ช่วยอะไร
Load Balancer (LB) รับทราฟฟิกที่ IP/โดเมนเดียว แล้วกระจายไปยังหลาย Droplet ด้านหลัง ได้ประโยชน์ 3 อย่าง
- รองรับทราฟฟิกมากขึ้น เพิ่มเครื่องแทนการอัปเกรดเครื่องเดียวไปเรื่อยๆ
- ความพร้อมใช้งานสูงขึ้น เครื่องใดล่ม LB หยุดส่งทราฟฟิกไปเครื่องนั้นเอง
- อัปเดตโดยไม่ล่ม ถอดทีละเครื่องออกมาอัปเดตแล้วใส่กลับ
องค์ประกอบสำคัญ
| ส่วน | หน้าที่ |
|---|---|
| Forwarding rules | บอกว่าพอร์ต/โปรโตคอลขาเข้าไปที่พอร์ตใดของ Droplet |
| Health checks | ตรวจว่า Droplet ตอบสนองดีไหม ถ้าไม่ดีจะถูกหยุดส่งงานให้ |
| Algorithm | วิธีเลือกเครื่อง เช่น round robin, least connections |
| Sticky sessions | ส่งผู้ใช้คนเดิมไปเครื่องเดิม (ผ่านคุกกี้) |
| SSL | จัดการ HTTPS ที่ LB หรือส่งผ่านถึงเครื่อง |
| Droplets / Tag | เครื่องเป้าหมาย เลือกทีละเครื่องหรือตาม tag |
ก่อนสร้าง LB
- Droplet เป้าหมายต้องอยู่ ภูมิภาคเดียวกับ LB (และควรอยู่ VPC เดียวกัน) ดู Cloud Firewall และ VPC
- แอปต้องรันได้บนหลายเครื่องพร้อมกัน (stateless หรือแชร์ session ได้)
- ทุกเครื่องมีโค้ดและการตั้งค่าเหมือนกัน (ใช้ snapshot คัดลอกเครื่องต้นแบบ)
สร้าง Load Balancer ทีละขั้น
- Control Panel → Networking → Load Balancers → Create
- เลือก ภูมิภาค และ VPC
- เลือก Droplet หรือ tag เป้าหมาย (เช่น
web) ใช้ tag จะรองรับเครื่องที่เพิ่มทีหลังอัตโนมัติ - ตั้ง Forwarding rules เช่น HTTP 80 → 80 และ HTTPS 443 → 80
- ตั้ง Health checks (ดูด้านล่าง)
- เลือก algorithm และ sticky sessions ตามต้องการ
- ตั้งชื่อแล้วกด Create
ตัวอย่าง forwarding rules
| Entry (LB) | Target (Droplet) | หมายเหตุ |
|---|---|---|
| HTTP :80 | HTTP :80 | แล้ว redirect ไป HTTPS |
| HTTPS :443 | HTTP :80 | SSL termination ที่ LB |
| HTTPS :443 | HTTPS :443 | SSL passthrough (เครื่องจัดการ SSL เอง) |
SSL ที่ Load Balancer
มี 3 โหมดหลักๆ
- SSL termination: LB ถอดรหัส HTTPS แล้วส่ง HTTP ธรรมดาไปหาเครื่อง ผ่านเครือข่ายภายใน ง่ายที่สุด จัดการใบรับรองที่เดียว
- SSL passthrough: LB ส่งทราฟฟิกที่เข้ารหัสต่อไปให้เครื่องถอดเอง ใช้เมื่อต้องการ end-to-end
- Re-encryption: ถอดที่ LB แล้วเข้ารหัสใหม่ไปยังเครื่อง
DigitalOcean รองรับการขอใบรับรอง Let's Encrypt จัดการให้ผ่าน LB (เมื่อโดเมนใช้ DNS ของ DigitalOcean ตามเงื่อนไขในเอกสาร) หรืออัปโหลดใบรับรองของคุณเอง ดู ตั้งค่า DNS บน DigitalOcean
แอปต้องรู้ว่าผู้ใช้มาจาก HTTPS
เมื่อ LB ถอด SSL เครื่องจะเห็นเป็น HTTP แอปต้องอ่านหัวข้อ X-Forwarded-Proto และ X-Forwarded-For เพื่อรู้โปรโตคอลและ IP จริง ตัวอย่างใน Nginx
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
ระบุช่วง IP ภายในของ LB ให้ตรงกับ VPC ของคุณ (ตรวจใน Control Panel)
Health Check
LB จะเรียกเครื่องเป็นระยะ ถ้าไม่ผ่านตามจำนวนครั้งที่กำหนดจะถือว่าไม่พร้อม
- Protocol: HTTP หรือ TCP
- Path: เช่น
/healthzควรเป็นหน้าเบาๆ ที่ตอบ 200 เมื่อแอป *และฐานข้อมูลที่จำเป็น* พร้อม - Interval / Timeout / Thresholds: ตั้งให้สมดุล ไวเกินไปจะตัดเครื่องที่แค่ช้าชั่วคราว
ตัวอย่าง endpoint ใน Express
app.get('/healthz', (req, res) => res.status(200).send('ok'));
อย่าให้ health check ชี้ไปหน้าแรกที่หนักและต้องล็อกอิน
Algorithm และ Sticky Sessions
- Round robin: หมุนไปทีละเครื่อง ง่ายและเหมาะที่สุดเมื่อคำขอใช้เวลาใกล้เคียงกัน
- Least connections: ส่งให้เครื่องที่มีการเชื่อมต่อน้อยสุด เหมาะกับคำขอที่ใช้เวลาไม่เท่ากัน เช่น WebSocket/อัปโหลด
- Sticky sessions: ผู้ใช้คนเดิมไปเครื่องเดิมตามคุกกี้ ใช้เป็นทางลัดเมื่อแอปเก็บ session ในหน่วยความจำของเครื่อง แต่ไม่ใช่วิธีที่ดีที่สุด
ทางออกที่ดีกว่า sticky
เก็บ session ไว้ที่กลาง เช่น Redis (Managed Redis/Valkey ดู คู่มือ Managed Databases) และเก็บไฟล์ที่ผู้ใช้อัปโหลดไว้ที่ คู่มือ Spaces Object Storage เพื่อให้ทุกเครื่องเห็นข้อมูลเดียวกัน
สถาปัตยกรรมตัวอย่าง
ผู้ใช้ → DNS (A record) → Load Balancer
│
┌────────────┴────────────┐
web-1 web-2 (tag: web)
└────────────┬────────────┘
Managed Database + Spaces
ข้อสำคัญคือ ข้อมูลที่เปลี่ยนแปลงต้องไม่อยู่บน web เครื่องใดเครื่องหนึ่ง ฐานข้อมูลอยู่ที่ Managed DB ไฟล์อยู่ที่ Spaces เซสชันอยู่ที่ Redis
ขั้นตอน deploy แบบไม่ล่ม (rolling)
- เอา web-1 ออกจาก LB (หรือทำให้ health check ไม่ผ่านชั่วคราว)
- อัปเดตโค้ดบน web-1 ทดสอบ
- ใส่กลับเข้า LB และรอให้ health check ผ่าน
- ทำซ้ำกับ web-2
ถ้าใช้ Deploy Node.js บน Droplet สามารถทำสคริปต์อัตโนมัติผ่าน doctl หรือ API ได้
ข้อจำกัดและข้อควรรู้
- LB เป็นจุดที่เพิ่มอีกชั้น มีค่าใช้จ่ายและต้องออกแบบแอปให้พร้อม
- LB ตัวเดียวทำงานในภูมิภาคเดียว ถ้าต้องการรอดทั้งภูมิภาคล่มต้องมีสถาปัตยกรรมหลายภูมิภาค (ซับซ้อนกว่านี้มาก)
- มีขีดจำกัดจำนวนการเชื่อมต่อ/ขนาด ขึ้นกับ size ของ LB ที่เลือก ตรวจในหน้า Pricing/Docs
- ไฟร์วอลล์ของ Droplet ควรรับเฉพาะทราฟฟิกจาก LB สำหรับพอร์ตเว็บ
ทางเลือกอื่นแทน LB
| ทางเลือก | เหมาะเมื่อ |
|---|---|
| เครื่องเดียวที่ใหญ่ขึ้น | ทราฟฟิกไม่สูง ต้องการง่ายและถูก |
| คู่มือ App Platform | ไม่อยากดูแล LB เอง ระบบจัดการให้ |
| คู่มือ Kubernetes (DOKS) | ใช้ Kubernetes Ingress/Service LoadBalancer |
| CDN หน้าเว็บ | เว็บเป็นไฟล์ static เป็นหลัก |
คำถามที่พบบ่อย
Load Balancer ต้องมีกี่ Droplet ถึงคุ้ม
เพื่อประโยชน์ด้านความพร้อมใช้งานควรมีอย่างน้อย 2 เครื่อง ถ้ามีเครื่องเดียวและต้องการแค่ SSL ฟรี Nginx + Certbot ถูกกว่า
ใช้ LB กับ WebSocket ได้ไหม
ได้ ควรใช้ algorithm แบบ least connections หรือ sticky sessions ตามลักษณะแอป และตรวจการตั้ง timeout ของการเชื่อมต่อ
ฐานข้อมูลควรอยู่หลัง LB ไหม
ไม่ LB ในบทความนี้ใช้กับ HTTP/TCP ของเว็บ ฐานข้อมูลควรเป็น Managed Database หรือมี replication ตามสถาปัตยกรรมของมัน
LB คิดค่าอะไรบ้าง
คิดตามขนาดของ LB รายเดือน และแบนด์วิดท์ส่วนเกินตามเงื่อนไขของบัญชี ดูตัวเลขล่าสุดที่หน้า Pricing ของ DigitalOcean