จัดกลุ่มหลาย Backend ด้วย Nginx Upstream
เรียนรู้การประกาศ upstream group และเลือกวิธีกระจาย request แบบ round robin, least connections, IP hash และ weight สำหรับระบบหลาย instance

ภาพรวม
Nginx ไม่ได้มีดีแค่เสิร์ฟไฟล์เว็บเร็ว ⚡
อีกความสามารถที่ทีม Dev และ DevOps ใช้กันหนักมาก คือการรวมหลาย backend ให้กลายเป็นก้อนเดียวผ่าน upstream 🧩
ถ้าระบบเริ่มมีหลาย service หลาย container หรือหลายเครื่อง การโยน traffic ไปหาแต่ละตัวแบบตรงๆ จะเริ่มจัดการยากทันที 😵
upstream ช่วยให้ Nginx รู้ว่า backend กลุ่มนี้มีสมาชิกอะไรบ้าง ควรกระจายโหลดแบบไหน และถ้าเครื่องไหนล่มควรข้ามไปหาใครแทน 🔁
มองง่ายๆ เหมือนตั้งชื่อทีมให้ server หลายตัว แทนที่จะจำ IP ทุกเครื่อง เราตั้งชื่อกลุ่มเดียว แล้วให้ Nginx จัดการต่อ 🎯
ตัวอย่างภาพจำ Frontend ส่ง request เข้า Nginx Nginx ดูว่าปลายทางต้องไปกลุ่ม backend ไหน จากนั้นค่อยเลือก server ในกลุ่มนั้นให้อัตโนมัติ 🛣️
แนวคิดนี้เจอบ่อยมากในระบบที่มี เว็บหลายเครื่อง API หลาย instance container หลายตัวใน Docker หรือ service ที่แยกตามงาน เช่น auth, payment, search 🐳
ตัวอย่างโครงสร้างแบบง่าย
upstream app_servers { server 10.0.0.11:3000; server 10.0.0.12:3000; server 10.0.0.13:3000; }
จากนั้นฝั่ง location ก็ส่งต่อเข้า upstream ที่ตั้งชื่อไว้
location / { proxy_pass http://app_servers; }
ผลลัพธ์คือ request ที่เข้ามาจะไม่วิ่งไปหาเครื่องเดียวตลอด แต่กระจายไปยังสมาชิกในกลุ่มตาม policy ที่ Nginx ใช้ 🚀
ค่าเริ่มต้นที่หลายคนไม่รู้คือ Nginx จะใช้แนว round robin เป็นหลัก หมายถึงส่ง request วนไปทีละเครื่องแบบเรียงคิว 📦
แต่ถ้าระบบต้องการพฤติกรรมเฉพาะ ก็ปรับได้ เช่น least_conn ให้เครื่องที่มี connection น้อยกว่ารับงานก่อน ip_hash ให้ user เดิมมีแนวโน้มไปเครื่องเดิม weight กำหนดน้ำหนักให้บางเครื่องรับโหลดมากกว่าเครื่องอื่น ⚖️
ตัวอย่างกรณีมีเครื่องแรงไม่เท่ากัน เครื่องใหม่แรงกว่า RAM เยอะกว่า ก็ให้ weight สูงกว่าได้ เช่นเครื่อง A รับ 3 ส่วน เครื่อง B รับ 1 ส่วน ช่วยใช้ทรัพยากรได้คุ้มขึ้น 💡
อีกจุดที่มีประโยชน์มากคือการทำ failover ถ้า backend ตัวหนึ่งไม่ตอบ Nginx สามารถข้ามไปตัวอื่นในกลุ่มได้ ทำให้หน้าเว็บไม่ล่มทั้งก้อนง่ายๆ 🛡️
หลายคนเพิ่งรู้ตอนระบบมีปัญหาว่า การมี backend หลายตัวอย่างเดียว ยังไม่พอ ถ้าไม่มีตัวกลางช่วยจัดเส้นทาง เราจะย้ายเครื่อง ปิดเครื่อง หรือ deploy แบบแทบไม่สะดวกเลย 😬
upstream ยังช่วยให้ config อ่านง่ายขึ้นมาก เพราะเราแยก “รายชื่อ backend” ออกจาก “กติกาการ route” เวลาเพิ่มหรือลบ server ก็แก้เป็นจุดๆ ได้ ✍️
ในโลก container ยิ่งสำคัญ เพราะ instance อาจเกิดและหายบ่อย ถ้าผูกปลายทางแบบ hardcode ทุกจุด maintenance จะเหนื่อยมาก 🧠
อีกเทคนิคที่คนทำระบบโตๆ ชอบใช้ คือแยก upstream ตามประเภทงาน เช่น app_read สำหรับงานอ่าน app_write สำหรับงานเขียน image_service สำหรับรูป admin_service สำหรับหลังบ้าน ทำให้ routing ชัดและดูแลง่ายขึ้น 🧭
สิ่งที่ควรระวังคือ บางระบบมี session ค้างใน memory ของแต่ละเครื่อง ถ้า request ของ user คนเดิมสลับเครื่องไปมา อาจเจออาการ login หลุด หรือข้อมูลหายได้ 🔐
ทางแก้ที่นิยมมี 2 ทาง ใช้ shared session เช่น Redis หรือใช้วิธี sticky behavior อย่าง ip_hash เท่าที่เหมาะสม แต่ระยะยาว shared session มักยืดหยุ่นกว่า 🧰
อีกมุมที่น่าสนใจ upstream ไม่ได้มีค่าแค่เรื่อง scale แต่มันเป็นรากฐานของการ deploy แบบลื่นขึ้นด้วย เช่นค่อยๆ เอาเครื่องใหม่เข้ากลุ่ม หรือถอดเครื่องเก่าออกทีละตัวโดยกระทบผู้ใช้น้อยลง 🌈
สรุปแบบสั้นจำง่าย upstream คือการตั้งชื่อและจัดกลุ่ม backend หลายตัว แล้วให้ Nginx เป็นคนเลือกว่าจะส่งงานไปเครื่องไหน พร้อมช่วยเรื่อง load balancing, failover และการจัดการ config ให้เป็นระบบ 📚
ใครดูแลเว็บที่เริ่มมีมากกว่า 1 backend แค่รู้จัก upstream ดีๆ ชีวิตจะง่ายขึ้นแบบรู้สึกได้จริง 🔧
บางครั้งความต่างระหว่างระบบที่ดูวุ่น กับระบบที่ดูโปร ไม่ได้อยู่ที่เขียนโค้ดเก่งกว่า แต่อยู่ที่วางทางเดินของ traffic ดีพอหรือยัง ✨
แนวทางนำไปใช้
- นำแนวคิดจากโพสต์นี้ไปทดลองกับงานจริงของคุณ
- แยกเป็นขั้นตอนเล็ก ๆ แล้วทำทีละส่วน
- บันทึกผลลัพธ์และสิ่งที่เรียนรู้เพื่อต่อยอด
สรุป
เรียนรู้การประกาศ upstream group และเลือกวิธีกระจาย request แบบ round robin, least connections, IP hash และ weight สำหรับระบบหลาย instance
แหล่งอ้างอิง
- http://app_servers;