โหลดบาลานซ์สำหรับเว็บไซต์แบรนด์: หลายอินสแตนซ์ ตรวจสอบสถานะ คงเซสชัน และสลับเมื่อล่ม
หนึ่ง、เมื่อไหร่ต้องใช้โหลดบาลานซ์ เมื่อไหร่คือออกแบบเกินความจำเป็น
โหลดบาลานซ์ไม่ใช่สิ่งที่ต้องมีตั้งแต่เริ่ม ยอดเข้าชมต่อวันไม่เกิน 5 พัน ใช้ VPS 2 คอร์ 4GB เครื่องเดียวรัน Nginx+PHP+MySQL ก็เพียงพอ จ่ายเงินไม่กี่ร้อยเพื่อซื้อ LB มีแต่เพิ่มความซับซ้อน สัญญาณที่บอกว่าต้องใช้หลายอินสแตนซ์จริง ๆ มีสามข้อ: CPU เครื่องเดียวเกิน 60% เป็นเวลานาน ต้องหยุดเว็บตอนปล่อยเวอร์ชันใหม่ หรือคุณเคยเสียออร์เดอร์เพราะเครื่องเดียวล่ม ถ้าเข้าเกณฑ์สองข้อ ค่อยขึ้น LB
เส้นทางการอัปเกรดของเว็บไซต์แบรนด์ทั่วไปคือ: VPS เครื่องเดียวรัน compose (ยอดเข้าชมต่อวันไม่เกิน 1 หมื่น) → แยก MySQL ไปเครื่องแยก (ยอดเข้าชมต่อวัน 3 หมื่น) → รันแอป 2 เครื่อง + cloud LB (ยอดเข้าชมต่อวัน 5 หมื่น) → รันแอป 3 ถึง 5 เครื่อง + autoscaling (ยอดเข้าชมต่อวันเกิน 2 แสน) อย่าข้ามขั้น CDN รับทราฟฟิก static ก่อน LB จะช่วยลดภาระต้นทางได้ครึ่งหนึ่ง ดูที่CDN เร่งความเร็วทั่วโลก。
| ระยะ | รูปแบบการติดตั้ง | จำนวนอินสแตนซ์แอป | ยอดเข้าชมต่อวันอ้างอิง | ค่าใช้จ่ายเพิ่มต่อเดือน |
|---|---|---|---|---|
| ช่วงเริ่มต้น | VPS เครื่องเดียว + compose | 1 | <1 หมื่น | 0 |
| ระยะเติบโต | แอป 1 เครื่อง + DB แยก 1 เครื่อง | 1 | 1 หมื่นถึง 5 หมื่น | +150 หยวน |
| ช่วงมั่นคง | แอป 2 เครื่อง + cloud LB | 2 | 5 หมื่นถึง 2 แสน | +ค่า LB ประมาณ 100 หยวน |
| ช่วงพีค | แอป 3 ถึง 5 เครื่อง + autoscaling | 3 ถึง 5 | >2 แสน | +คิดค่าบริการรายชั่วโมง |
สอง、L4 หรือ L7: เว็บไซต์แบรนด์ควรเลือกระดับไหน
โหลดบาลานซ์แบ่งเป็นชั้นสี่ (L4 ส่งต่อตาม TCP/IP) และชั้นเจ็ด (L7 ส่งต่อตามพาธ HTTP) L4 ประสิทธิภาพสูง ตั้งค่าง่าย แต่ส่งต่อได้ตามพอร์ตเท่านั้น ส่วน L7 กำหนดเส้นทางตามโดเมน พาธ และ Header ได้ อีกทั้งทำ canary release และ HTTPS offload ได้ เว็บไซต์แบรนด์เลือก L7 เพราะคุณต้องแยกเส้นทางตามพาธ: ไฟล์ static ไป CDN, API ไปแอป, หลังบ้านไปอีกกลุ่มอินสแตนซ์
การเลือก LB ของผู้ให้บริการคลาวด์: AWS ใช้ ALB (Application Load Balancer), Alibaba Cloud ใช้ SLB หรือ ALB, Tencent Cloud ใช้ CLB ทั้งสามมีฟังก์ชันทับซ้อนกัน ราคาเริ่มต้น 100-200 หยวนต่อเดือน เกณฑ์ตัดสินง่ายๆ: ถ้าความต้องการของคุณมีแค่ “สลับสองเครื่องแบบวนรอบ” ใช้ L4 LB ที่ถูกที่สุด ถ้าต้องการ route ตาม path, ทำ canary release, แยก traffic ตามโดเมน เลือก L7 LB
| รายการเปรียบเทียบ | L4 TCP Load Balancing | L7 HTTP Load Balancing |
|---|---|---|
| เกณฑ์การส่งต่อ | IP+พอร์ต | โดเมน/path/Header/Cookie |
| ประสิทธิภาพ | สูงมาก ระดับไมโครวินาที | ต่ำกว่าเล็กน้อย ระดับมิลลิวินาที |
| การถอด HTTPS | ไม่รองรับ | รองรับ วาง certificate ที่ LB |
| Canary Release | ไม่รองรับการแบ่งตามสัดส่วน traffic | รองรับการสลับ traffic ตามน้ำหนัก |
| เหมาะกับเว็บไซต์อิสระ | สลับสองเครื่องแบบวนรอบง่ายๆ | route หลาย path, canary |
| ค่าบริการรายเดือนอ้างอิง | ประมาณ 80-120 หยวน | ประมาณ 150-250 หยวน |
สาม、Health Check: ตั้งค่าอย่างไรไม่ให้ตัดเครื่องผิด
Health Check เป็นหัวใจของ LB ตั้งหลวมเกินไป เครื่องที่ล่มยังรับ traffic อยู่ ตั้งตึงเกินไป แอปเพิ่งเริ่มช้าไปนิดเดียวก็ถูกตัดออก ทำให้เกิด avalanche การตั้งค่ามาตรฐานสำหรับเว็บไซต์อิสระคือ: path ตรวจสอบ /health (คืนค่าแค่ 200 ไม่ query ฐานข้อมูล เพื่อไม่ให้ DB ช้าลามมาถึง LB), interval 10 วินาที, ล้มเหลวติดกัน 3 ครั้งจึงตัดออก, สำเร็จติดกัน 2 ครั้งจึงคืนสถานะ
endpoint /health ต้องเบา ข้อผิดพลาดที่พบบ่อยคือให้มัน query MySQL หนึ่งครั้ง พอฐานข้อมูลกระตุก instance แอปทั้งหมดก็ถูก LB ตัดออก กลายเป็น 503 ทั้งเว็บ วิธีที่ถูกคือ /health คืนค่าแค่สถานะว่า process ยังอยู่ ส่วนสุขภาพฐานข้อมูลให้ใช้ endpoint /health/db แยกต่างหาก ใช้แค่ monitor ไม่ร่วมตัดสินใจตัดออก เกณฑ์แจ้งเตือนของ monitoring ดูได้ที่การมอนิเตอร์และแจ้งเตือนเว็บไซต์。
| พารามิเตอร์ | ค่าที่แนะนำ | คำอธิบาย | ข้อผิดพลาดที่พบบ่อย |
|---|---|---|---|
| path ตรวจสอบ | GET /health | ไม่ query DB คืนค่าแค่ 200 | query DB ทำให้ถูกตัดทั้งหมด |
| interval ตรวจสอบ | 10 วินาที | สมดุลระหว่างความไวและการตัดผิด | 1 วินาทีดุดันเกินไป |
| timeout | 5 วินาที | เกินกว่านับเป็นล้มเหลวหนึ่งครั้ง | 1 วินาทีสั้นเกินไป |
| เกณฑ์ unhealthy | ล้มเหลวติดกัน 3 ครั้ง | ตัด node ออก | ล้มเหลวครั้งเดียวก็ตัด |
| เกณฑ์สุขภาพ | สำเร็จติดกัน 2 ครั้ง | คืนสถานะเข้า queue | สำเร็จครั้งเดียวก็คืนสถานะ |
| response code | 200 นับว่า healthy | code อื่นนับว่าล้มเหลว | นับ 503 เป็น healthy |
สี่、Session Persistence: ไม่เปิดจะดีที่สุด
หลายคนพอขึ้น multi-instance ครั้งแรกก็คิดทันทีว่า “ผู้ใช้ login ที่เครื่อง A พอ request ถัดไปวิ่งไปเครื่อง B ก็หลุดสิ” เลยเปิด session persistence นี่เป็นวิธีที่ประหยัดเวลาระยะสั้นแต่เป็นหนี้ระยะยาว ปัญหาของ session persistence คือ: พอเครื่อง A ล่ม ผู้ใช้ที่ sticky อยู่กับเครื่อง A ทั้งหมดหลุด ความหมายของ failover ก็หายไปครึ่งหนึ่ง
วิธีที่ถูกคือย้าย session ออกจาก memory ของแอป PHP ใช้ Redis เก็บ session, Node ใช้ JWT แบบ stateless token, สถานะ login รวมศูนย์ไว้ที่ shared storage เดียว วิธีนี้ instance แอปตัวไหนก็จัดการ request ของผู้ใช้คนไหนก็ได้ เครื่องใดเครื่องหนึ่งล่มก็ไม่กระทบผู้ใช้ที่ออนไลน์อยู่ มีแค่สองกรณีที่ควรเปิด session persistence: ระบบเก่าแก้ไม่ได้ หรือปลั๊กอินบุคคลที่สามพึ่งพา local session อย่างหนัก
| รูปแบบ session | ความสามารถขยาย | ผลกระทบเมื่อล่ม | ต้นทุนการย้าย | ระดับการแนะนำ |
|---|---|---|---|---|
| session ไฟล์ในเครื่อง | แย่ ต้อง sticky | เครื่องเดียวล่ม = ผู้ใช้หลุด | ต่ำ | ไม่แนะนำ |
| Redis รวม session | ดี | สลับได้แบบไม่รู้สึก | ปานกลาง แก้ config ก็พอ | แนะนำ |
| JWT แบบไม่เก็บสถานะ | ดีที่สุด | สลับได้แบบไม่รู้สึก | สูง ต้องแก้ระบบยืนยันตัวตน | แนะนำสำหรับโปรเจกต์ใหม่ |
| LB ผูก session ด้วย cookie | แย่ | เครื่องที่ผูกไว้ล่ม ผู้ใช้ก็หลุด | ต่ำ แค่เปิดสวิตช์ | ใช้ชั่วคราวช่วงเปลี่ยนผ่านเท่านั้น |
ห้า、การสลับเมื่อเกิดข้อขัดข้อง: จะยืนยันได้อย่างไรว่า LB ของคุณสลับจริง
ตั้งค่า LB เสร็จไม่ได้แปลว่าการสลับเมื่อเกิดข้อขัดข้องทำงานแล้ว หลายทีมพอขึ้นระบบจริงก็ไม่เคยลองฆ่าเครื่องสักเครื่อง จนกระทั่งเครื่องล่มจริงถึงพบว่า LB ไม่ได้ตั้ง health check ไว้เลย หรือ security group ไม่ได้เปิดพอร์ตให้ ต้องซ้อมสลับก่อนขึ้นระบบจริงทุกครั้ง: ในสภาพแวดล้อมโปรดักชัน (หรือ pre-production) ลองสั่งปิดแอป A ด้วยมือ แล้วดูว่า LB สลับทราฟฟิกไปที่ B ภายใน 30 วินาทีหรือไม่ และคำขอของผู้ใช้สะดุดหรือไม่
กับดักอีกข้อที่พบบ่อยคืออินสแตนซ์แอปสองตัวอยู่บนเครื่องกายภาพเดียวกันหรือตู้แร็คเดียวกัน พอไฟดับทั้งแร็คก็ล่มพร้อมกันทั้งคู่ อย่างน้อยควรกระจายอย่างน้อยสอง availability zone (AZ) หรืออย่างน้อยสองโฮสต์ที่ต่างกัน ระเบียบวิธีเต็ม ๆ เรื่องการซ้อมสำรองและกู้คืนดูได้ที่การสำรองและกู้คืนเว็บไซต์。
ตัวอย่างสถานการณ์: เว็บ B2B แห่งหนึ่งเดิมรัน WordPress บน VPS เครื่องเดียว คืนหนึ่งโฮสต์ปิดปรับปรุงแล้วไฟดับ เว็บล่ม 4 ชั่วโมง พลาดอีเมลสอบถามจากลูกค้ายุโรป 3 ฉบับ หลังจากนั้นจึงเพิ่มอินสแตนซ์แอปตัวที่สองผูกกับ cloud LB ย้าย session ไปเก็บใน Redis และกระจายข้าม availability zone พอถึงรอบปิดปรับปรุงอีกครั้ง อินสแตนซ์ B รับทราฟฟิกทั้งหมดไปเอง ทั้งลูกค้าและฝ่ายขายไม่รู้สึกอะไร ค่าเครื่องเพิ่มเดือนละ 300 หยวนถูกกว่ามูลค่าอีเมลสอบถามที่หายไปตอนเว็บล่มมาก
| สถานการณ์ซ้อม | การดำเนินการ | ผลลัพธ์ที่คาดหวัง | ถ้าไม่ผ่านทำอย่างไร |
|---|---|---|---|
| ฆ่าโปรเซสแอป | systemctl stop app | LB ถอดออกภายใน 30 วินาที ทราฟฟิกสลับไป B | ตรวจเส้นทาง health check |
| ตัดเน็ตของแอป | iptables บล็อกพอร์ต | ถอดออกภายใน 10 วินาที | ตรวจ security group ว่าเปิดวงเน็ตของ LB แล้วหรือยัง |
| รีสตาร์ตเครื่อง | reboot | กลับเข้าคิวอัตโนมัติหลังบูต | ตรวจสคริปต์ตอนบูตและ health |
| ฐานข้อมูลกระตุก | จำลอง slow query | แอปไม่ถูกถอดออกผิดพลาด | health ต้องไม่ตรวจ DB |
| สลับทราฟฟิกทั้งหมดไป B | ปรับ weight ไปที่ B เป็น 100 | B รับคนเดียวได้ 5 นาที | ทดสอบความสามารถในการรับโหลดของ B |
FAQ คำถามที่พบบ่อย
ผู้เข้าชมต่อวันเท่าไรจึงต้องใช้โหลดบาลานซ์?
สรุปแล้วควรเปิด session persistence ไหม?
ทำไม health check ถึงตรวจฐานข้อมูลไม่ได้?
เอา two instances ไปวางบนเครื่อง physical เครื่องเดียวกันได้ไหม
LB ของผู้ให้บริการคลาวด์คิดค่าบริการเดือนละเท่าไร
จะยืนยันได้อย่างไรว่า failover ทำงานจริง
ทิ้งท้าย
คุณค่าของ load balancing สำหรับเว็บไซต์แบรนด์ตัวเอง ครึ่งหนึ่งคือรับทราฟฟิก อีกครึ่งหนึ่งคือรับมือกับเหตุขัดข้อง อย่างแรกหลายคนคำนวณออก อย่างหลังมักถูกมองข้าม ต้นทุนของอินสแตนซ์แอปเพิ่มอีกหนึ่งเครื่อง แลกมาด้วยการที่เครื่องใดเครื่องหนึ่งล่มแล้วผู้ใช้ไม่รู้สึก ซึ่งในสถานการณ์ B2B ที่มี inquiry นั่นคือเงิน
ลงมือสามขั้น ขั้นแรกทำให้แอปเป็น stateless ย้าย session ไป Redis ขั้นที่สองเปิดอินสแตนซ์เครื่องที่สอง ต่อไว้หลัง LB ของคลาวด์ ตั้งค่า health check ให้เรียบร้อย ขั้นที่สามซ้อม kill โปรเซสหนึ่งครั้ง ยืนยันว่าทราฟฟิกสลับไปภายใน 30 วินาที ครบสามขั้นนี้ สถาปัตยกรรมหลายอินสแตนซ์จึงจะใช้งานได้จริง ส่วน monitoring และ alert ที่ต้องมีดูที่การมอนิเตอร์และแจ้งเตือนเว็บไซต์ ส่วนการขยายและลดอัตโนมัติแบบขั้นสูงดูที่การขยายและลดอัตโนมัติ。
ประโยคเดียวที่จำได้ขึ้นใจ ความหมายของ load balancing ไม่ใช่การกระจายทราฟฟิก แต่คือการทำให้เมื่อเครื่องใดเครื่องหนึ่งล่ม ผู้ใช้และ inquiry ไม่รู้สึกถึงมันเลย
