
ในโลกดิจิทัลที่เปลี่ยนแปลงอย่างรวดเร็วในปัจจุบัน ประสิทธิภาพและความเสถียรของเว็บไซต์หรือแอปพลิเคชันออนไลน์คือหัวใจสำคัญในการสร้างประสบการณ์ที่ดีให้กับผู้ใช้งานและรักษาความน่าเชื่อถือทางธุรกิจครับ เมื่อจำนวนผู้เข้าชมเพิ่มขึ้นอย่างรวดเร็ว การพึ่งพาเซิร์ฟเวอร์เพียงตัวเดียวอาจนำไปสู่ปัญหาคอขวด (bottleneck) และ Single Point of Failure (SPOF) ที่ร้ายแรงได้ ซึ่งจะส่งผลให้เว็บไซต์ของคุณหยุดทำงานหรือทำงานได้ช้าลงอย่างมากในช่วงเวลาที่มีผู้ใช้งานหนาแน่นครับ
นี่คือจุดที่เทคโนโลยีอย่าง Nginx Reverse Proxy Load Balancing เข้ามามีบทบาทสำคัญ Nginx ไม่ได้เป็นเพียงแค่เว็บเซิร์ฟเวอร์ประสิทธิภาพสูงเท่านั้น แต่ยังเป็นเครื่องมือที่ทรงพลังในการจัดการทราฟฟิก (traffic management) และกระจายโหลดงาน (workload distribution) ไปยังเซิร์ฟเวอร์แบ็กเอนด์ (backend servers) หลาย ๆ ตัวได้อย่างชาญฉลาด ทำให้แอปพลิเคชันของคุณสามารถรองรับผู้ใช้งานจำนวนมหาศาลได้อย่างราบรื่นและต่อเนื่อง ทั้งยังเพิ่มความทนทานต่อความผิดพลาด (fault tolerance) ได้อย่างมีนัยสำคัญครับ
บทความฉบับนี้จาก SiamLancard.com จะพาคุณเจาะลึกทุกแง่มุมของการตั้งค่า Nginx Reverse Proxy Load Balancing ตั้งแต่แนวคิดพื้นฐานไปจนถึงการตั้งค่าขั้นสูง พร้อมตัวอย่างโค้ดที่ใช้งานได้จริง เพื่อให้คุณสามารถนำไปประยุกต์ใช้กับระบบของคุณได้อย่างมั่นใจ ไม่ว่าคุณจะเป็นนักพัฒนา ผู้ดูแลระบบ หรือเจ้าของธุรกิจที่ต้องการยกระดับโครงสร้างพื้นฐานดิจิทัลของคุณ บทความนี้คือคู่มือที่คุณกำลังมองหาครับ
พร้อมแล้วหรือยังครับ? มาเริ่มต้นการเดินทางสู่การสร้างระบบที่แข็งแกร่งและมีประสิทธิภาพไปด้วยกันเลยครับ!
สารบัญ
- บทนำ: ทำไม Nginx Reverse Proxy Load Balancing จึงสำคัญสำหรับคุณ?
- สถาปัตยกรรมพื้นฐานของ Nginx Reverse Proxy Load Balancing
- การเตรียมความพร้อมก่อนเริ่มต้น (Pre-requisites)
- Nginx Reverse Proxy: การตั้งค่าพื้นฐาน
- Nginx Load Balancing: กลไกและอัลกอริทึม
- คู่มือตั้งค่า Nginx Reverse Proxy Load Balancing แบบ Step-by-Step
- ฟีเจอร์ขั้นสูงสำหรับ Nginx Reverse Proxy Load Balancing
- การเปรียบเทียบ Nginx Load Balancing อัลกอริทึม
- การตรวจสอบและแก้ไขปัญหา (Troubleshooting)
- คำถามที่พบบ่อย (FAQ)
- สรุปและก้าวต่อไป
บทนำ: ทำไม Nginx Reverse Proxy Load Balancing จึงสำคัญสำหรับคุณ?
ในยุคที่ทุกธุรกิจขับเคลื่อนด้วยดิจิทัล การมีเว็บไซต์หรือแอปพลิเคชันที่ทำงานได้อย่างรวดเร็ว เสถียร และพร้อมใช้งานตลอดเวลา ไม่ใช่แค่ความได้เปรียบอีกต่อไป แต่เป็นสิ่งจำเป็นพื้นฐานเลยครับ คุณคงไม่อยากให้ลูกค้าต้องหงุดหงิดกับหน้าเว็บที่โหลดช้า หรือแย่ไปกว่านั้นคือเว็บไซต์ล่มในช่วงเวลาสำคัญใช่ไหมครับ?
ปัญหาที่คุณอาจกำลังเผชิญ
- Single Point of Failure (SPOF): หากคุณมีเว็บเซิร์ฟเวอร์เพียงเครื่องเดียว หากเครื่องนั้นเกิดปัญหาขึ้น เว็บไซต์ของคุณก็จะหยุดทำงานทันทีครับ
- Performance Bottleneck: เมื่อมีผู้ใช้งานจำนวนมากเข้ามาพร้อมกัน เซิร์ฟเวอร์เดียวอาจไม่สามารถประมวลผลคำขอทั้งหมดได้อย่างรวดเร็ว ทำให้เว็บโหลดช้าหรือค้างไปเลยครับ
- Scalability Limits: การเพิ่มประสิทธิภาพของเซิร์ฟเวอร์เครื่องเดียวมีขีดจำกัด ไม่ว่าจะเป็น CPU, RAM หรือ I/O ซึ่งในที่สุดก็จะไม่เพียงพอต่อความต้องการที่เพิ่มขึ้นครับ
- Maintenance Downtime: การอัปเดตหรือบำรุงรักษาเซิร์ฟเวอร์จำเป็นต้องมีการหยุดทำงาน (downtime) ซึ่งส่งผลกระทบต่อผู้ใช้งานครับ
Nginx คืออะไร?
Nginx (อ่านว่า “เอ็นจิ้น-เอ็กซ์”) คือเว็บเซิร์ฟเวอร์โอเพนซอร์สที่มีประสิทธิภาพสูงและได้รับความนิยมอย่างแพร่หลายทั่วโลกครับ Nginx ถูกออกแบบมาเพื่อจัดการกับการเชื่อมต่อพร้อมกันจำนวนมาก (concurrent connections) ได้อย่างยอดเยี่ยม ด้วยสถาปัตยกรรมแบบ Asynchronous, Event-driven ซึ่งแตกต่างจากเว็บเซิร์ฟเวอร์แบบ Thread-based อย่าง Apache ทำให้ Nginx สามารถใช้ทรัพยากรได้อย่างมีประสิทธิภาพมากกว่าและรองรับทราฟฟิกสูง ๆ ได้ดีกว่าครับ
นอกจากบทบาทหลักในฐานะเว็บเซิร์ฟเวอร์แล้ว Nginx ยังมีความสามารถที่หลากหลาย เช่น Reverse Proxy, Load Balancer, HTTP Cache, และ SSL/TLS Terminator ซึ่งทำให้มันเป็นเครื่องมือที่ขาดไม่ได้ในโครงสร้างพื้นฐานของเว็บไซต์และแอปพลิเคชันสมัยใหม่ครับ
Reverse Proxy คืออะไร?
ลองจินตนาการว่าคุณมีบ้านหลังหนึ่ง (Backend Server) และมีผู้คนมากมายอยากมาเยี่ยมบ้านของคุณ (Client) แทนที่จะให้ทุกคนตรงเข้ามาที่บ้านโดยตรง คุณมี รปภ. คอยยืนอยู่หน้าประตูรั้ว (Reverse Proxy) ครับ
Reverse Proxy คือเซิร์ฟเวอร์ที่อยู่ด้านหน้าของเว็บเซิร์ฟเวอร์จริง (Backend Servers) ทำหน้าที่เป็นตัวกลางรับคำขอจากไคลเอนต์ (เช่น เว็บบราวเซอร์) แล้วส่งต่อคำขอเหล่านั้นไปยังเว็บเซิร์ฟเวอร์แบ็กเอนด์ที่เหมาะสม จากนั้นก็จะรับการตอบกลับจากแบ็กเอนด์มาส่งคืนให้กับไคลเอนต์อีกทีครับ
หน้าที่หลักของ Reverse Proxy คือ:
- Security: ซ่อน IP Address และรายละเอียดของ Backend Servers จากภายนอก ทำให้เพิ่มความปลอดภัยครับ
- Load Balancing: กระจายคำขอไปยัง Backend Servers หลาย ๆ ตัว (ซึ่งเป็นหัวข้อหลักของเราในวันนี้ครับ)
- Caching: เก็บสำเนาการตอบกลับบางส่วนไว้ เพื่อลดภาระของ Backend Servers และเพิ่มความเร็วในการส่งข้อมูลครับ
- SSL/TLS Termination: จัดการการเข้ารหัส/ถอดรหัสข้อมูล SSL/TLS แทน Backend Servers ครับ
Load Balancing คืออะไร?
เมื่อมีคำขอจำนวนมากเข้ามาพร้อมกัน หากส่งไปยังเซิร์ฟเวอร์เดียวทั้งหมด เซิร์ฟเวอร์นั้นก็อาจจะทำงานหนักเกินไปจนล่มได้ครับ Load Balancing คือกลไกที่เข้ามาช่วยแก้ปัญหานี้ครับ
Load Balancing คือกระบวนการกระจายปริมาณงาน (workload) ของเครือข่ายหรือแอปพลิเคชันไปยังเซิร์ฟเวอร์หลาย ๆ ตัวครับ โดยมีเป้าหมายเพื่อเพิ่มความพร้อมใช้งาน (availability), เพิ่มประสิทธิภาพ (performance) และขยายขนาด (scalability) ของระบบโดยรวมครับ
Load Balancer จะทำหน้าที่เป็น “ผู้จัดการการจราจร” คอยตรวจสอบสถานะของ Backend Servers และเลือกเซิร์ฟเวอร์ที่เหมาะสมที่สุดในการประมวลผลคำขอแต่ละรายการ โดยใช้อัลกอริทึมต่าง ๆ เช่น Round Robin, Least Connected หรือ IP Hash ครับ
ประโยชน์ของการใช้ Nginx Reverse Proxy Load Balancing
การนำ Nginx มาใช้ร่วมกับ Reverse Proxy และ Load Balancing มอบประโยชน์มากมายให้กับระบบของคุณครับ:
- เพิ่มความพร้อมใช้งาน (High Availability): หาก Backend Server ตัวใดตัวหนึ่งเกิดล้มเหลว Nginx จะหยุดส่งคำขอไปยังเซิร์ฟเวอร์นั้นชั่วคราวและส่งไปยังเซิร์ฟเวอร์อื่นที่ยังทำงานอยู่แทน ทำให้บริการของคุณยังคงใช้งานได้ต่อเนื่องครับ
- ปรับปรุงประสิทธิภาพ (Improved Performance): การกระจายโหลดงานไปยังเซิร์ฟเวอร์หลายตัวช่วยให้แต่ละเซิร์ฟเวอร์ไม่ทำงานหนักเกินไป ทำให้คำขอถูกประมวลผลได้เร็วขึ้น และลดเวลาในการตอบสนอง (latency) ครับ
- ความสามารถในการปรับขนาด (Scalability): คุณสามารถเพิ่ม Backend Servers เข้าไปในกลุ่มได้อย่างง่ายดายเมื่อปริมาณทราฟฟิกเพิ่มขึ้น โดยไม่ต้องปรับเปลี่ยนคอนฟิกูเรชันของไคลเอนต์ครับ
- เพิ่มความปลอดภัย (Enhanced Security): Nginx ทำหน้าที่เป็นด่านหน้า ทำให้ Backend Servers ถูกซ่อนจากอินเทอร์เน็ตโดยตรง ลดความเสี่ยงจากการโจมตีครับ
- ลดเวลา Downtime ในการบำรุงรักษา: คุณสามารถนำ Backend Server ออกจากกลุ่มเพื่อบำรุงรักษาหรืออัปเดตได้ทีละตัว โดยไม่กระทบต่อการทำงานของระบบโดยรวมครับ
- SSL/TLS Termination: Nginx สามารถจัดการการเข้ารหัส SSL/TLS ได้ ทำให้ Backend Servers ไม่ต้องรับภาระนี้ และสามารถใช้ทรัพยากรไปกับการประมวลผลแอปพลิเคชันได้เต็มที่ครับ
ด้วยประโยชน์เหล่านี้ Nginx Reverse Proxy Load Balancing จึงเป็นโซลูชันที่ทรงพลังและจำเป็นสำหรับโครงสร้างพื้นฐานของเว็บและแอปพลิเคชันที่ต้องการความเสถียร ประสิทธิภาพ และความยืดหยุ่นสูงครับ
สถาปัตยกรรมพื้นฐานของ Nginx Reverse Proxy Load Balancing
เพื่อให้เห็นภาพรวมที่ชัดเจนยิ่งขึ้น เรามาดูส่วนประกอบหลักและหลักการทำงานของ Nginx Reverse Proxy Load Balancing กันครับ
ส่วนประกอบหลัก
- Client (ไคลเอนต์): คือผู้ใช้งานที่ส่งคำขอ HTTP/HTTPS จากเว็บบราวเซอร์หรือแอปพลิเคชันไปยังเว็บไซต์หรือบริการของคุณครับ
- Nginx Reverse Proxy (Load Balancer): นี่คือหัวใจสำคัญของระบบ เป็นเซิร์ฟเวอร์ Nginx ที่ทำหน้าที่เป็นตัวกลางรับคำขอทั้งหมดจากไคลเอนต์ ทำการประมวลผลเบื้องต้น (เช่น SSL Termination, Caching) และกระจายคำขอไปยัง Backend Servers ครับ
- Backend Servers (Web Servers/Application Servers): คือเซิร์ฟเวอร์จริงที่รันเว็บแอปพลิเคชันของคุณอยู่ เช่น Apache, Node.js, PHP-FPM, Python Django/Flask, Java Spring Boot เป็นต้น เซิร์ฟเวอร์เหล่านี้จะประมวลผลคำขอและส่งข้อมูลกลับมายัง Nginx Reverse Proxy ครับ
- Database (ฐานข้อมูล – อ่านเพิ่มเติม): แม้จะไม่ใช่ส่วนหนึ่งของการทำ Load Balancing โดย Nginx โดยตรง แต่ก็เป็นส่วนสำคัญของแอปพลิเคชันส่วนใหญ่ครับ Backend Servers จะเชื่อมต่อกับฐานข้อมูลเพื่อดึงและจัดเก็บข้อมูล แอปพลิเคชันที่ออกแบบมาดีควรมีฐานข้อมูลแยกต่างหากและอาจมีการทำ Database Load Balancing หรือ Replication ของตัวเองครับ
หลักการทำงาน
กระบวนการทำงานของ Nginx Reverse Proxy Load Balancing สามารถอธิบายได้เป็นขั้นตอนดังนี้ครับ:
- Client Request: ผู้ใช้งานเปิดเว็บบราวเซอร์และพิมพ์ URL ของเว็บไซต์ของคุณ (เช่น
www.yourdomain.com) - DNS Resolution: DNS server จะแปลงชื่อโดเมนเป็น IP Address ของ Nginx Reverse Proxy ครับ
- Request to Nginx: คำขอ HTTP/HTTPS จากไคลเอนต์จะถูกส่งตรงมายัง Nginx Reverse Proxy
- Nginx Processes Request:
- Nginx รับคำขอและตรวจสอบคอนฟิกูเรชัน
- หากมีการตั้งค่า SSL/TLS Termination ที่ Nginx, Nginx จะจัดการการถอดรหัสข้อมูลครับ
- Nginx อาจตรวจสอบแคช หากมีข้อมูลที่ร้องขออยู่ในแคชและยังไม่หมดอายุ Nginx ก็จะส่งข้อมูลจากแคชกลับไปยังไคลเอนต์ทันที โดยไม่ต้องส่งไปยัง Backend Servers ครับ
- Load Balancing: หากคำขอต้องถูกส่งไปยัง Backend Servers, Nginx จะใช้อัลกอริทึม Load Balancing ที่กำหนดไว้ (เช่น Round Robin, Least Connected) เพื่อเลือก Backend Server ที่เหมาะสมที่สุดในการประมวลผลคำขอครับ
- Proxy to Backend: Nginx ส่งต่อคำขอไปยัง Backend Server ที่เลือก
- Backend Processes Request: Backend Server รับคำขอ ประมวลผล (เช่น รันโค้ด PHP, ดึงข้อมูลจาก Database) และสร้างการตอบกลับ HTTP/HTTPS
- Response to Nginx: Backend Server ส่งการตอบกลับนั้นกลับมายัง Nginx Reverse Proxy
- Nginx Sends Response: Nginx รับการตอบกลับจาก Backend Server แล้วส่งกลับไปยังไคลเอนต์ ในขั้นตอนนี้ Nginx อาจมีการเข้ารหัส SSL/TLS อีกครั้งหากมีการทำ SSL Termination ที่ Nginx และไคลเอนต์ร้องขอผ่าน HTTPS ครับ
- Client Receives Response: ไคลเอนต์ได้รับข้อมูลและแสดงผลบนเว็บบราวเซอร์
กระบวนการนี้จะเกิดขึ้นซ้ำ ๆ กับทุกคำขอ ทำให้มั่นใจได้ว่าทราฟฟิกจะถูกกระจายอย่างมีประสิทธิภาพ และระบบมีความยืดหยุ่นสูงในการจัดการกับโหลดงานที่ผันผวนครับ
การเตรียมความพร้อมก่อนเริ่มต้น (Pre-requisites)
ก่อนที่เราจะเริ่มตั้งค่า Nginx Reverse Proxy Load Balancing เราต้องเตรียมสภาพแวดล้อมให้พร้อมก่อนครับ นี่คือสิ่งที่คุณจะต้องมีและขั้นตอนการติดตั้ง Nginx เบื้องต้นครับ
สิ่งที่คุณต้องมี
- เซิร์ฟเวอร์ Nginx: เซิร์ฟเวอร์ Linux (เช่น Ubuntu Server, CentOS Stream, Debian) ที่คุณจะใช้ติดตั้ง Nginx เพื่อทำหน้าที่เป็น Reverse Proxy และ Load Balancer ครับ (ขอเรียกว่า “Nginx Server”)
- Backend Servers อย่างน้อย 2 ตัว: เซิร์ฟเวอร์เพิ่มเติมอย่างน้อย 2 ตัว (หรือมากกว่า) ที่รันเว็บแอปพลิเคชันของคุณอยู่ เช่น Apache, Node.js, PHP-FPM, Docker Containers เป็นต้น เซิร์ฟเวอร์เหล่านี้ควรมี IP Address ที่แตกต่างกันและ Nginx Server สามารถเข้าถึงได้ครับ (ขอเรียกว่า “Backend Server 1”, “Backend Server 2” และอื่น ๆ)
- ความเข้าใจพื้นฐานเกี่ยวกับ Linux Command Line: คุณจะต้องใช้คำสั่งพื้นฐานในการติดตั้ง ซ่อมบำรุง และแก้ไขไฟล์คอนฟิกูเรชันครับ
- สิทธิ์ root หรือ sudo: สำหรับการติดตั้งและแก้ไขไฟล์ระบบครับ
- Text Editor: เช่น
nano,vimหรือVS Codeสำหรับแก้ไขไฟล์คอนฟิกูเรชัน
การติดตั้ง Nginx (บน Ubuntu/CentOS)
เราจะติดตั้ง Nginx บนเซิร์ฟเวอร์ที่เรากำหนดให้เป็น Nginx Server ครับ
บน Ubuntu/Debian:
อัปเดตแพ็คเกจและติดตั้ง Nginx:
sudo apt update
sudo apt install nginx -y
หลังจากติดตั้งเสร็จ Nginx จะถูกตั้งค่าให้รันโดยอัตโนมัติครับ คุณสามารถตรวจสอบสถานะได้โดย:
sudo systemctl status nginx
คุณควรเห็นสถานะเป็น active (running) ครับ
บน CentOS/RHEL (เวอร์ชัน 7 ขึ้นไป):
ก่อนอื่นต้องเพิ่ม Nginx repository เนื่องจาก Nginx อาจจะไม่ได้อยู่ใน repository พื้นฐานของ CentOS/RHEL ครับ
sudo yum install epel-release -y
sudo yum update
sudo yum install nginx -y
หลังจากติดตั้ง ให้เปิดใช้งาน Nginx และเริ่มบริการ:
sudo systemctl enable nginx
sudo systemctl start nginx
ตรวจสอบสถานะ:
sudo systemctl status nginx
การตั้งค่า Firewall (สำคัญ):
หากคุณใช้ Firewall (เช่น UFW บน Ubuntu หรือ firewalld บน CentOS) คุณต้องอนุญาตให้ Nginx รับการเชื่อมต่อผ่านพอร์ต HTTP (80) และ HTTPS (443) ครับ
บน Ubuntu (UFW):
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS' # หากคุณจะใช้ HTTPS
sudo ufw enable # หากยังไม่ได้เปิดใช้งาน
sudo ufw status
บน CentOS (firewalld):
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https # หากคุณจะใช้ HTTPS
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
เมื่อติดตั้ง Nginx และตั้งค่า Firewall เรียบร้อยแล้ว คุณสามารถลองเข้าถึง IP Address ของ Nginx Server ผ่านเว็บบราวเซอร์ได้ครับ คุณควรจะเห็นหน้า “Welcome to Nginx!” ครับ
Nginx Reverse Proxy: การตั้งค่าพื้นฐาน
ก่อนที่เราจะลงลึกไปถึง Load Balancing มาทำความเข้าใจการตั้งค่า Nginx ให้ทำงานเป็น Reverse Proxy พื้นฐานก่อนครับ
ไฟล์คอนฟิกูเรชันหลักของ Nginx
ไฟล์คอนฟิกูเรชันหลักของ Nginx มักจะอยู่ที่ /etc/nginx/nginx.conf ครับ ไฟล์นี้จะทำหน้าที่รวมคอนฟิกูเรชันย่อย ๆ จากไดเรกทอรีอื่น ๆ เข้ามาใช้งาน
/etc/nginx/nginx.conf: ไฟล์คอนฟิกูเรชันหลัก/etc/nginx/sites-available/: ไดเรกทอรีสำหรับเก็บไฟล์คอนฟิกูเรชันของแต่ละเว็บไซต์ (server block) ที่คุณสร้างขึ้น/etc/nginx/sites-enabled/: ไดเรกทอรีนี้จะเก็บลิงก์สัญลักษณ์ (symbolic links) ไปยังไฟล์คอนฟิกูเรชันที่อยู่ในsites-availableครับ Nginx จะโหลดเฉพาะไฟล์ที่อยู่ในsites-enabledเท่านั้น
โดยปกติแล้ว เราจะสร้างไฟล์คอนฟิกูเรชันใหม่ใน /etc/nginx/sites-available/ แล้วสร้างลิงก์ไปยัง /etc/nginx/sites-enabled/ ครับ
การสร้าง Server Block สำหรับ Reverse Proxy
สมมติว่าคุณมี Backend Server หนึ่งตัวรันแอปพลิเคชันอยู่บน IP 192.168.1.101 ที่พอร์ต 8000 และคุณต้องการให้ Nginx รับคำขอจากภายนอกที่พอร์ต 80 แล้วส่งต่อไปยัง Backend Server นี้ครับ
สร้างไฟล์คอนฟิกูเรชันใหม่ เช่น /etc/nginx/sites-available/mywebapp.conf:
# /etc/nginx/sites-available/mywebapp.conf
server {
listen 80; # Nginx จะฟังคำขอที่พอร์ต 80
server_name yourdomain.com www.yourdomain.com; # กำหนดชื่อโดเมนของคุณ
location / {
# ส่งต่อคำขอทั้งหมดไปยัง Backend Server ที่ 192.168.1.101 พอร์ต 8000
proxy_pass http://192.168.1.101:8000;
# กำหนด Headers เพื่อส่งข้อมูลของ Client ไปยัง Backend Server
# X-Forwarded-For: IP Address เดิมของ Client
# X-Forwarded-Proto: โปรโตคอลเดิม (HTTP/HTTPS)
# Host: Host header เดิมของ Client
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;
}
}
คำอธิบาย:
listen 80;: Nginx จะรับการเชื่อมต่อที่พอร์ต 80 (HTTP) ครับserver_name yourdomain.com www.yourdomain.com;: กำหนดชื่อโดเมนที่ Nginx จะตอบสนองครับlocation / { ... }: บล็อกนี้ระบุว่าคำขอทั้งหมดที่เข้ามาจะถูกจัดการอย่างไรครับproxy_pass http://192.168.1.101:8000;: นี่คือหัวใจของการทำ Reverse Proxy ครับ Nginx จะส่งต่อคำขอไปยัง URL ที่ระบุ ซึ่งก็คือ Backend Server ของเรานั่นเองครับproxy_set_header ...;: บรรทัดเหล่านี้มีความสำคัญมากครับ มันจะส่งข้อมูลเฮดเดอร์ของคำขอเดิมจากไคลเอนต์ไปยัง Backend Server ครับ หากไม่มีสิ่งเหล่านี้ Backend Server อาจเข้าใจผิดว่า Nginx เป็นไคลเอนต์และไม่ได้รับข้อมูลที่ถูกต้อง เช่น IP Address จริงของผู้ใช้งานครับ
หลังจากสร้างไฟล์คอนฟิกูเรชันแล้ว ให้เปิดใช้งานโดยสร้าง symbolic link และทดสอบคอนฟิกูเรชัน:
sudo ln -s /etc/nginx/sites-available/mywebapp.conf /etc/nginx/sites-enabled/
sudo nginx -t # ทดสอบว่าคอนฟิกูเรชันถูกต้องหรือไม่
หากไม่มีข้อผิดพลาด ให้ Reload Nginx เพื่อใช้การตั้งค่าใหม่ครับ:
sudo systemctl reload nginx
ตอนนี้ Nginx ของคุณก็ทำงานเป็น Reverse Proxy แล้วครับ คำขอที่เข้ามายัง yourdomain.com จะถูกส่งต่อไปยัง 192.168.1.101:8000 ครับ
Nginx Load Balancing: กลไกและอัลกอริทึม
เมื่อเราเข้าใจการทำ Reverse Proxy แล้ว ขั้นตอนต่อไปคือการเพิ่ม Backend Servers หลาย ๆ ตัวเข้ามา และให้ Nginx ทำหน้าที่กระจายโหลดครับ Nginx ใช้ upstream block ในการกำหนดกลุ่มของ Backend Servers และระบุอัลกอริทึมการกระจายโหลดครับ
อัลกอริทึม Load Balancing ยอดนิยม
Nginx รองรับอัลกอริทึม Load Balancing หลายแบบ โดยแต่ละแบบมีจุดเด่นและเหมาะกับสถานการณ์ที่แตกต่างกันไปครับ
-
Round Robin (ค่าเริ่มต้น):
- หลักการ: Nginx จะกระจายคำขอไปยัง Backend Servers ในกลุ่มตามลำดับวนไปเรื่อย ๆ ครับ เช่น Server A, Server B, Server C, Server A, Server B, Server C…
- การใช้งาน: เป็นอัลกอริทึมที่ง่ายที่สุดและเป็นค่าเริ่มต้น เหมาะสำหรับ Backend Servers ที่มีประสิทธิภาพเท่ากันและใช้ทรัพยากรใกล้เคียงกันครับ
- ตัวอย่าง:
upstream backend_servers { server 192.168.1.101:8000; server 192.168.1.102:8000; server 192.168.1.103:8000; }หากไม่ระบุอัลกอริทึม Nginx จะใช้ Round Robin โดยอัตโนมัติครับ
-
Weighted Round Robin:
- หลักการ: คล้ายกับ Round Robin แต่คุณสามารถกำหนด “น้ำหนัก” (weight) ให้กับแต่ละ Backend Server ได้ครับ เซิร์ฟเวอร์ที่มีน้ำหนักมากกว่าจะได้รับคำขอมากกว่าครับ
- การใช้งาน: เหมาะสำหรับกรณีที่ Backend Servers มีความสามารถในการประมวลผลไม่เท่ากัน เช่น มีเซิร์ฟเวอร์ใหม่ที่แรงกว่า หรือเซิร์ฟเวอร์เก่าที่ประสิทธิภาพน้อยกว่าครับ
- ตัวอย่าง:
upstream backend_servers { server 192.168.1.101:8000 weight=3; # Server นี้จะได้รับ 3 เท่าของโหลด server 192.168.1.102:8000 weight=1; # Server นี้จะได้รับ 1 เท่าของโหลด }
-
Least Connected:
- หลักการ: Nginx จะส่งคำขอไปยัง Backend Server ที่มีการเชื่อมต่อที่ใช้งานอยู่ (active connections) น้อยที่สุดในขณะนั้นครับ
- การใช้งาน: มีประสิทธิภาพดีกว่า Round Robin ในกรณีที่คำขอใช้เวลาประมวลผลไม่เท่ากัน เหมาะสำหรับแอปพลิเคชันที่ต้องใช้เวลาในการประมวลผลคำขอแต่ละรายการแตกต่างกันไปครับ
- ตัวอย่าง:
upstream backend_servers { least_conn; # ระบุอัลกอริทึม Least Connected server 192.168.1.101:8000; server 192.168.1.102:8000; }
-
IP Hash:
- หลักการ: Nginx จะใช้ IP Address ของไคลเอนต์เป็นตัวกำหนดว่าจะส่งคำขอไปยัง Backend Server ใดครับ โดยใช้ฟังก์ชัน Hash เพื่อให้ IP เดิมถูกส่งไปยัง Backend Server เดิมเสมอ
- การใช้งาน: มีประโยชน์มากสำหรับการทำ Session Persistence หรือ “Sticky Sessions” ซึ่งเป็นกรณีที่ผู้ใช้คนเดิมต้องการเชื่อมต่อไปยัง Backend Server ตัวเดิมตลอดการใช้งาน เพื่อรักษาสถานะของ Session ไว้ครับ
- ตัวอย่าง:
upstream backend_servers { ip_hash; # ระบุอัลกอริทึม IP Hash server 192.168.1.101:8000; server 192.168.1.102:8000; }
-
Generic Hash:
- หลักการ: คล้ายกับ IP Hash แต่คุณสามารถกำหนดค่าที่ใช้ในการทำ Hash ได้เองครับ โดยใช้ตัวแปรของ Nginx หรือข้อความใด ๆ ก็ได้
- การใช้งาน: มีความยืดหยุ่นสูง สามารถใช้ในการสร้าง Sticky Sessions ตามข้อมูลอื่น ๆ ที่ไม่ใช่แค่ IP Address เช่น Cookie หรือ URL parameter ครับ
- ตัวอย่าง:
upstream backend_servers { hash $request_uri consistent; # ใช้ URI ของคำขอในการทำ Hash server 192.168.1.101:8000; server 192.168.1.102:8000; }
-
Random:
- หลักการ: Nginx จะเลือก Backend Server แบบสุ่มครับ
- การใช้งาน: อาจใช้เพื่อทดสอบ หรือในสถานการณ์ที่ไม่ต้องการความลำเอียงในการกระจายโหลด แต่โดยทั่วไปแล้วอัลกอริทึมอื่น ๆ จะมีประสิทธิภาพดีกว่าในการกระจายโหลดงานจริงครับ
- ตัวอย่าง:
upstream backend_servers { random; # เลือกแบบสุ่ม server 192.168.1.101:8000; server 192.168.1.102:8000; }
การเลือกอัลกอริทึมที่เหมาะสม
การเลือกอัลกอริทึมขึ้นอยู่กับลักษณะของแอปพลิเคชันของคุณครับ
- ถ้า Backend Servers มีประสิทธิภาพเท่ากันและคำขอใช้เวลาประมวลผลใกล้เคียงกัน Round Robin หรือ Weighted Round Robin (หากมีเซิร์ฟเวอร์ประสิทธิภาพต่างกัน) เป็นตัวเลือกที่ดีและง่ายต่อการใช้งานครับ
- หากคำขอใช้เวลาประมวลผลไม่เท่ากัน Least Connected มักจะให้ผลลัพธ์ที่ดีกว่าในการกระจายโหลดที่แท้จริงครับ
- หากแอปพลิเคชันของคุณต้องการรักษา Session (Sticky Sessions) และ Session ไม่ได้จัดการที่ระดับฐานข้อมูลหรือ Redis, IP Hash เป็นวิธีมาตรฐานที่ Nginx มีให้ครับ
ในบทความนี้ เราจะเน้นที่อัลกอริทึมพื้นฐานและใช้บ่อยที่สุดเพื่อเป็นแนวทางในการเริ่มต้นครับ
คู่มือตั้งค่า Nginx Reverse Proxy Load Balancing แบบ Step-by-Step
ตอนนี้เราจะมาตั้งค่า Nginx ให้เป็น Load Balancer แบบเต็มรูปแบบครับ สมมติว่าเรามี Backend Servers สองตัวดังนี้:
- Backend Server 1:
192.168.1.101:8000 - Backend Server 2:
192.168.1.102:8000
และ Nginx Server ของเรามี IP 192.168.1.100 ครับ
ขั้นตอนที่ 1: กำหนด Backend Servers ใน Block `upstream`
เราจะสร้างบล็อก upstream เพื่อกำหนดกลุ่มของ Backend Servers ที่ Nginx จะกระจายโหลดไปให้ครับ บล็อก upstream นี้มักจะอยู่ในไฟล์คอนฟิกูเรชันของ server block หรือในไฟล์หลัก nginx.conf ก็ได้ครับ เพื่อความเรียบร้อย เราจะสร้างไฟล์แยกออกมาใน /etc/nginx/conf.d/ หรือใส่ไว้ใน server block ครับ ในตัวอย่างนี้จะใส่ไว้ใน /etc/nginx/sites-available/ ร่วมกับ server block ครับ
แก้ไขไฟล์ /etc/nginx/sites-available/mywebapp.conf (หรือสร้างใหม่) โดยเพิ่ม upstream block เข้าไปด้านบนสุดของไฟล์ (แต่ยังอยู่ในส่วน http block ของ nginx.conf นะครับ)
# /etc/nginx/sites-available/mywebapp.conf
# กำหนดกลุ่มของ Backend Servers
upstream backend_servers {
# ใช้อัลกอริทึม Load Balancing แบบ Least Connected
# ซึ่งจะส่งคำขอไปยังเซิร์ฟเวอร์ที่มีการเชื่อมต่อใช้งานน้อยที่สุด
least_conn;
# Backend Server ตัวที่ 1
# max_fails=3: หาก Nginx ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์นี้ได้ 3 ครั้ง
# fail_timeout=10s: จะถือว่าเซิร์ฟเวอร์นี้ล้มเหลวและหยุดส่งคำขอไป 10 วินาที
server 192.168.1.101:8000 max_fails=3 fail_timeout=10s;
# Backend Server ตัวที่ 2
server 192.168.1.102:8000 max_fails=3 fail_timeout=10s;
# หากมี Backend Server ตัวที่ 3 ที่ประสิทธิภาพด้อยกว่า
# สามารถเพิ่ม weight เพื่อลดจำนวนคำขอที่ส่งไป หรือ backup เพื่อใช้เมื่อเซิร์ฟเวอร์หลักล้มเหลว
# server 192.168.1.103:8000 weight=1 backup;
}
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# ... ส่วนของ location block จะอยู่ด้านล่าง ...
}
คำอธิบาย upstream directives:
upstream backend_servers { ... }: สร้างกลุ่มเซิร์ฟเวอร์ชื่อbackend_serversครับleast_conn;: ระบุอัลกอริทึม Least Connected ครับ หากไม่ระบุ จะใช้ Round Robin โดยอัตโนมัติserver 192.168.1.101:8000;: กำหนด IP Address และพอร์ตของ Backend Server ครับmax_fails=3: Nginx จะพยายามเชื่อมต่อกับเซิร์ฟเวอร์นี้ 3 ครั้ง หากล้มเหลวทั้งหมด Nginx จะถือว่าเซิร์ฟเวอร์นี้ไม่พร้อมใช้งานชั่วคราวครับfail_timeout=10s: เมื่อเซิร์ฟเวอร์ถูกทำเครื่องหมายว่าไม่พร้อมใช้งาน Nginx จะหยุดส่งคำขอไปยังเซิร์ฟเวอร์นี้เป็นเวลา 10 วินาที หลังจากนั้น Nginx จะลองส่งคำขอไปยังเซิร์ฟเวอร์นี้อีกครั้งเพื่อตรวจสอบว่ากลับมาทำงานปกติหรือยังครับweight=N: (ไม่แสดงในตัวอย่างหลัก) กำหนดน้ำหนักให้เซิร์ฟเวอร์ครับ เซิร์ฟเวอร์ที่มีน้ำหนัก 2 จะได้รับคำขอเป็นสองเท่าของเซิร์ฟเวอร์ที่มีน้ำหนัก 1 ครับbackup: (ไม่แสดงในตัวอย่างหลัก) กำหนดให้เซิร์ฟเวอร์นี้เป็นเซิร์ฟเวอร์สำรอง จะถูกใช้งานก็ต่อเมื่อเซิร์ฟเวอร์หลักทั้งหมดไม่พร้อมใช้งานครับdown: (ไม่แสดงในตัวอย่างหลัก) ทำเครื่องหมายว่าเซิร์ฟเวอร์นี้ไม่พร้อมใช้งาน จะไม่ถูกใช้ในการกระจายโหลดจนกว่าจะถูกลบออกหรือแก้ไขครับ
ขั้นตอนที่ 2: ตั้งค่า Server Block สำหรับ Load Balancer
ใน server block เราจะบอก Nginx ว่าให้ส่งต่อคำขอไปยังกลุ่ม upstream ที่เราสร้างไว้ครับ
เพิ่มหรือแก้ไข server block ในไฟล์ /etc/nginx/sites-available/mywebapp.conf:
# /etc/nginx/sites-available/mywebapp.conf
# ... (upstream block ที่สร้างไว้ด้านบน) ...
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location / {
# proxy_pass ไปยังชื่อ upstream group ที่เรากำหนดไว้
proxy_pass http://backend_servers; # ชี้ไปยังกลุ่ม backend_servers
# ... ส่วนของ proxy_set_header จะตามมาในขั้นตอนถัดไป ...
}
}
ตอนนี้แทนที่จะระบุ IP Address และพอร์ตของ Backend Server โดยตรงใน proxy_pass เราใช้ชื่อของ upstream group แทนครับ (http://backend_servers;)
ขั้นตอนที่ 3: กำหนดพารามิเตอร์เพิ่มเติมสำหรับ Proxy (Headers, Timeout, Buffering)
การกำหนดพารามิเตอร์เหล่านี้ช่วยให้การสื่อสารระหว่าง Nginx และ Backend Servers เป็นไปอย่างราบรื่นและมีประสิทธิภาพครับ
# /etc/nginx/sites-available/mywebapp.conf
# ... (upstream block) ...
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# พารามิเตอร์ที่ใช้ร่วมกันใน location block นี้
location / {
proxy_pass http://backend_servers;
# ส่งต่อ Headers สำคัญไปยัง Backend Server
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 สำหรับการเชื่อมต่อไปยัง Backend Server
# proxy_connect_timeout: เวลาสูงสุดในการสร้างการเชื่อมต่อ (Default: 60s)
# proxy_send_timeout: เวลาสูงสุดในการส่งคำขอไปยัง Backend (Default: 60s)
# proxy_read_timeout: เวลาสูงสุดในการรอการตอบกลับจาก Backend (Default: 60s)
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# กำหนดขนาดบัฟเฟอร์สำหรับการรับข้อมูลจาก Backend Server
# proxy_buffering: เปิด/ปิดการทำ buffering (Default: on)
# proxy_buffer_size: ขนาดของบัฟเฟอร์สำหรับ head ของ response
# proxy_buffers: จำนวนและขนาดของบัฟเฟอร์สำหรับ body ของ response
# proxy_busy_buffers_size: ขนาดสูงสุดของบัฟเฟอร์ที่ "busy" (ถูกใช้โดย Nginx)
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
# หาก Backend Server มีการบีบอัดข้อมูล (gzip) ให้ Nginx จัดการ
proxy_set_header Accept-Encoding ""; # ป้องกัน Backend บีบอัดซ้ำ
proxy_redirect off; # ป้องกันปัญหาการเปลี่ยนเส้นทางที่ไม่ถูกต้อง
}
}
คำอธิบายพารามิเตอร์เพิ่มเติม:
proxy_set_header Host $host;: ส่ง Host header เดิมของไคลเอนต์ไปให้ Backend Server เพื่อให้ Backend รู้ว่าคำขอถูกส่งมาจากโดเมนใด (สำคัญมากสำหรับแอปพลิเคชันที่ใช้ Virtual Hosts)proxy_set_header X-Real-IP $remote_addr;: ส่ง IP Address จริงของไคลเอนต์ไปให้ Backend Serverproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;: เป็นมาตรฐานในการส่ง IP Address ของไคลเอนต์และ proxy servers ที่คำขอเดินทางผ่านไปให้ Backend Server ครับproxy_set_header X-Forwarded-Proto $scheme;: บอก Backend Server ว่าไคลเอนต์เชื่อมต่อมาด้วยโปรโตคอล HTTP หรือ HTTPS ครับproxy_connect_timeout,proxy_send_timeout,proxy_read_timeout: เป็นการตั้งค่าเวลารอคอย (timeout) เพื่อป้องกันไม่ให้ Nginx ค้างรอ Backend Server นานเกินไปหาก Backend มีปัญหาหรือทำงานช้าครับproxy_buffering on;: Nginx จะเก็บการตอบกลับจาก Backend Server ไว้ในบัฟเฟอร์ก่อนที่จะส่งไปให้ไคลเอนต์ ช่วยเพิ่มประสิทธิภาพและลดการใช้ทรัพยากรของ Backend ครับproxy_buffer_size,proxy_buffers,proxy_busy_buffers_size: กำหนดขนาดและจำนวนของบัฟเฟอร์ที่ Nginx ใช้ในการเก็บข้อมูลจาก Backend Server ครับ การตั้งค่าที่เหมาะสมช่วยให้ Nginx จัดการกับไฟล์ขนาดใหญ่หรือการตอบกลับที่ซับซ้อนได้ดีขึ้นครับproxy_redirect off;: ป้องกันปัญหาการเปลี่ยนเส้นทาง (redirect) ของ Backend Server ที่อาจระบุ URL ผิดพลาดเมื่อทำงานอยู่หลัง Reverse Proxy ครับ
ขั้นตอนที่ 4: การทดสอบคอนฟิกูเรชันและ Reload Nginx
หลังจากที่คุณแก้ไขไฟล์คอนฟิกูเรชันเสร็จสิ้นแล้ว สิ่งสำคัญที่สุดคือการตรวจสอบความถูกต้องของไวยากรณ์ (syntax) ก่อนที่จะโหลดการตั้งค่าใหม่ครับ
sudo nginx -t
หากคอนฟิกูเรชันถูกต้อง คุณจะเห็นข้อความประมาณนี้:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
หากมีข้อผิดพลาด Nginx จะแจ้งตำแหน่งและประเภทของข้อผิดพลาดครับ ให้คุณกลับไปแก้ไขให้ถูกต้อง
เมื่อมั่นใจว่าคอนฟิกูเรชันถูกต้องแล้ว ให้ Reload Nginx เพื่อให้ใช้การตั้งค่าใหม่ครับ:
sudo systemctl reload nginx
ตอนนี้ Nginx ของคุณก็พร้อมที่จะทำหน้าที่เป็น Reverse Proxy Load Balancer แล้วครับ คุณสามารถทดสอบโดยการเข้าถึง yourdomain.com และดูว่าคำขอถูกกระจายไปยัง Backend Servers ทั้งสองหรือไม่ (คุณอาจจะต้องตรวจสอบ Log ของ Backend Servers เพื่อยืนยันครับ)
ตัวอย่างคอนฟิกูเรชันที่สมบูรณ์
นี่คือตัวอย่างคอนฟิกูเรชันทั้งหมดที่อยู่ในไฟล์ /etc/nginx/sites-available/mywebapp.conf (พร้อมคอมเมนต์):
# /etc/nginx/sites-available/mywebapp.conf
# ไฟล์คอนฟิกูเรชันสำหรับ Nginx Reverse Proxy Load Balancing
# สร้างกลุ่มของ Backend Servers
# ชื่อของกลุ่มคือ 'backend_servers'
upstream backend_servers {
# ใช้อัลกอริทึม Least Connected
# Nginx จะส่งคำขอไปยังเซิร์ฟเวอร์ที่มีการเชื่อมต่อที่ใช้งานอยู่ (active connections) น้อยที่สุด
least_conn;
# กำหนด Backend Server ตัวที่ 1
# IP: 192.168.1.101, Port: 8000
# max_fails=3: หาก Nginx ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์นี้ได้ 3 ครั้ง
# fail_timeout=10s: จะถือว่าเซิร์ฟเวอร์นี้ล้มเหลวและหยุดส่งคำขอไป 10 วินาที
server 192.168.1.101:8000 max_fails=3 fail_timeout=10s;
# กำหนด Backend Server ตัวที่ 2
# IP: 192.168.1.102, Port: 8000
server 192.168.1.102:8000 max_fails=3 fail_timeout=10s;
# สามารถเพิ่ม Backend Servers ได้ตามต้องการ
# server 192.168.1.103:8000 max_fails=3 fail_timeout=10s;
# ตัวอย่างการใช้ Weighted Round Robin (ถ้ามีเซิร์ฟเวอร์ประสิทธิภาพต่างกัน)
# server 192.168.1.101:8000 weight=3;
# server 192.166.1.102:8000 weight=1;
# ตัวอย่างการทำ Session Persistence ด้วย IP Hash
# ip_hash;
# server 192.168.1.101:8000;
# server 192.168.1.102:8000;
}
# กำหนด Server Block สำหรับการรับคำขอจากภายนอก
server {
listen 80; # Nginx จะฟังคำขอ HTTP ที่พอร์ต 80
listen [::]:80; # รองรับ IPv6 ด้วย
# กำหนดชื่อโดเมนที่ Nginx จะตอบสนอง
server_name yourdomain.com www.yourdomain.com;
# กำหนด Document Root (หากต้องการเสิร์ฟไฟล์บางอย่างจาก Nginx โดยตรง)
# root /var/www/html;
# กำหนดไฟล์ Log สำหรับการเข้าถึงและข้อผิดพลาดของ Server Block นี้
access_log /var/log/nginx/yourdomain.com_access.log;
error_log /var/log/nginx/yourdomain.com_error.log;
# บล็อก location สำหรับการจัดการคำขอทั้งหมด
location / {
# ส่งต่อคำขอทั้งหมดไปยังกลุ่ม Backend Servers ที่เรากำหนดไว้
proxy_pass http://backend_servers;
# ส่งต่อ Headers สำคัญของคำขอจาก Client ไปยัง Backend Server
# Host: ส่ง Host header เดิมของ Client (เช่น yourdomain.com)
proxy_set_header Host $host;
# X-Real-IP: ส่ง IP Address จริงของ Client
proxy_set_header X-Real-IP $remote_addr;
# X-Forwarded-For: ส่ง IP Address ของ Client และ Proxy Servers ที่คำขอเดินทางผ่าน
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# X-Forwarded-Proto: บอก Backend ว่า Client เชื่อมต่อมาด้วย HTTP หรือ HTTPS
proxy_set_header X-Forwarded-Proto $scheme;
# ป้องกันปัญหาการเปลี่ยนเส้นทาง (redirect) ของ Backend Server
proxy_redirect off;
# กำหนด timeout สำหรับการเชื่อมต่อไปยัง Backend Server
# เวลาสูงสุดในการสร้างการเชื่อมต่อ
proxy_connect_timeout 60s;
# เวลาสูงสุดในการส่งคำขอไปยัง Backend
proxy_send_timeout 60s;
# เวลาสูงสุดในการรอการตอบกลับจาก Backend
proxy_read_timeout 60s;
# กำหนดขนาดบัฟเฟอร์สำหรับการรับข้อมูลจาก Backend Server
# เปิดใช้งาน buffering (ค่าเริ่มต้นคือ on)
proxy_buffering on;
# ขนาดบัฟเฟอร์สำหรับ head ของ response
proxy_buffer_size 128k;
# จำนวนและขนาดของบัฟเฟอร์สำหรับ body ของ response
proxy_buffers 4 256k;
# ขนาดสูงสุดของบัฟเฟอร์ที่ "busy" (ถูกใช้โดย Nginx)
proxy_busy_buffers_size 256k;
# หาก Backend Server มีการบีบอัดข้อมูล (gzip)
# บรรทัดนี้ช่วยให้ Nginx จัดการการบีบอัดเอง แทนที่จะให้ Backend ทำซ้ำ
proxy_set_header Accept-Encoding "";
# สามารถกำหนดค่าอื่น ๆ เช่น Error Pages เฉพาะ
# error_page 500 502 503 504 /50x.html;
}
# สามารถเพิ่ม location blocks อื่นๆ ได้ตามความต้องการ
# เช่น สำหรับ static files, API endpoints
# location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
# expires 30d;
# add_header Cache-Control "public, no-transform";
# proxy_pass http://backend_servers;
# }
# สำหรับการจัดการ error pages
# error_page 404 /404.html;
# location = /404.html {
# internal;
# }
}
ฟีเจอร์ขั้นสูงสำหรับ Nginx Reverse Proxy Load Balancing
นอกจากการกระจายโหลดพื้นฐานแล้ว Nginx ยังมีฟีเจอร์ขั้นสูงมากมายที่ช่วยเพิ่มประสิทธิภาพ ความปลอดภัย และความยืดหยุ่นให้กับระบบ Load Balancing ของคุณครับ
การทำ Health Checks สำหรับ Backend Servers
Nginx มีกลไก Health Check พื้นฐานที่อยู่ใน upstream block โดยใช้พารามิเตอร์ max_fails และ fail_timeout ที่เราได้กล่าวไปแล้วครับ
เมื่อ Nginx พยายามเชื่อมต่อไปยัง Backend Server แล้วล้มเหลวครบ max_fails ครั้งภายในช่วงเวลา fail_timeout Nginx จะถือว่าเซิร์ฟเวอร์นั้น “down” และจะไม่ส่งคำขอไปให้ชั่วคราวเป็นเวลา fail_timeout ครับ
upstream backend_servers {
least_conn;
server 192.168.1.101:8000 max_fails=3 fail_timeout=10s; # ตรวจสอบ 3 ครั้งใน 10 วินาที
server 192.168.1.102:8000 max_fails=3 fail_timeout=10s;
}
นี่คือ Health Check พื้นฐานที่ตรวจสอบการเชื่อมต่อ TCP ครับ หากต้องการ Health Check ที่ซับซ้อนขึ้น (เช่น ตรวจสอบว่าแอปพลิเคชันตอบกลับ HTTP Status 200 OK หรือไม่) คุณอาจต้องใช้ Nginx Plus (เวอร์ชันเสียเงิน) หรือใช้ร่วมกับเครื่องมืออื่น ๆ เช่น Nginx Lua module หรือ Keepalived ครับ
การจัดการ Session Persistence (Sticky Sessions)
ในบางแอปพลิเคชัน สถานะของผู้ใช้งาน (session) อาจถูกเก็บไว้บน Backend Server ตัวใดตัวหนึ่งครับ หากผู้ใช้งานถูกสลับไปมาระหว่าง Backend Servers ที่ต่างกัน Session ก็อาจจะหายไปได้ครับ การทำ Session Persistence หรือ Sticky Sessions คือการทำให้คำขอจากผู้ใช้งานคนเดิมถูกส่งไปยัง Backend Server ตัวเดิมเสมอครับ
Nginx มีวิธีพื้นฐานในการทำ Sticky Sessions ด้วยอัลกอริทึม ip_hash:
upstream backend_servers {
ip_hash; # ใช้ IP Address ของ Client เป็นตัวกำหนด Backend Server
server 192.168.1.101:8000;
server 192.168.1.102:8000;
}
ข้อควรระวัง:
- หากผู้ใช้งานหลายคนมาจาก IP Address เดียวกัน (เช่น อยู่หลัง NAT หรือ Proxy ขององค์กร) พวกเขาจะถูกส่งไปยัง Backend Server ตัวเดียวกัน ซึ่งอาจทำให้ Backend Server นั้นรับโหลดมากเกินไปครับ
- หาก Backend Server ที่ถูกกำหนดด้วย IP Hash ล้มเหลว ผู้ใช้คนนั้นจะไม่สามารถเข้าถึงบริการได้จนกว่าเซิร์ฟเวอร์จะกลับมาทำงานครับ
วิธีที่ดีที่สุดในการจัดการ Session คือการใช้ Shared Session Storage เช่น Redis, Memcached หรือ Database ที่ Backend Servers ทุกตัวสามารถเข้าถึงได้ครับ (อ่านเพิ่มเติมเกี่ยวกับ Redis)
SSL/TLS Termination ที่ Nginx Reverse Proxy
การทำ SSL/TLS Termination ที่ Nginx หมายความว่า Nginx จะเป็นผู้รับผิดชอบในการถอดรหัสและเข้ารหัสข้อมูล SSL/TLS ครับ Backend Servers จะรับคำขอเป็น HTTP ธรรมดา ทำให้ลดภาระของ Backend Servers และทำให้การจัดการ Certificate ง่ายขึ้นครับ
คุณจะต้องมี SSL Certificate (เช่น จาก Let’s Encrypt) และ Private Key ครับ
server {
listen 443 ssl; # ฟังคำขอ HTTPS ที่พอร์ต 443
listen [::]:443 ssl;
server_name yourdomain.com www.yourdomain.com;
# ระบุไฟล์ SSL Certificate และ Private Key
ssl_certificate /etc/nginx/ssl/yourdomain.com.crt;
ssl_certificate_key /etc/nginx/ssl/yourdomain.com.key;
# กำหนดค่า SSL/TLS ที่แนะนำเพื่อความปลอดภัย
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1; # สำหรับ Nginx >= 1.1.0
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on; # Requires OCSP stapling from your CA
ssl_stapling_verify on; # Requires OCSP stapling from your CA
resolver 8.8.8.8 8.8.4.4 valid=300s; # DNS resolver for OCSP
resolver_timeout 5s;
# เพิ่ม HTTP Strict Transport Security (HSTS) เพื่อบังคับใช้ HTTPS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
location / {
proxy_pass http://backend_servers;
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; # สำคัญมากสำหรับ SSL termination
# ... (พารามิเตอร์ proxy อื่นๆ) ...
}
}
# Optional: Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}
การทำ Caching ด้วย Nginx
Nginx สามารถทำหน้าที่เป็น HTTP Cache ได้ด้วยการเก็บสำเนาการตอบกลับจาก Backend Servers ไว้ชั่วคราว เมื่อมีคำขอซ้ำ Nginx ก็จะส่งข้อมูลจากแคชโดยตรงโดยไม่ต้องส่งไปที่ Backend Servers อีก ซึ่งช่วยลดภาระและเพิ่มความเร็วในการตอบสนองได้อย่างมากครับ
ขั้นตอนการตั้งค่า Caching:
- กำหนด Cache Zone: ต้องกำหนดพื้นที่สำหรับเก็บแคช (Cache Zone) ใน
httpblock ในไฟล์/etc/nginx/nginx.confหรือไฟล์ย่อยที่ถูก include ครับ - เปิดใช้งาน Cache ใน Location Block: กำหนดให้
locationblock ใช้ Cache Zone นั้นครับ
# ใน /etc/nginx/nginx.conf หรือไฟล์ย่อยที่ถูก include
http {
# ... อื่นๆ ...
# กำหนด Cache Zone ชื่อ my_cache_zone
# /var/cache/nginx: ตำแหน่งที่เก็บไฟล์แคช
# levels: กำหนดโครงสร้างไดเรกทอรีของแคช (1:2 หมายถึง 2 ระดับย่อย)
# keys_zone: กำหนดชื่อและขนาดของพื้นที่ในหน่วยความจำสำหรับเก็บ metadata ของแคช (10MB)
# inactive: ระยะเวลาที่ข้อมูลในแคชจะถูกเก็บไว้หากไม่มีการเข้าถึง (60 นาที)
# max_size: ขนาดสูงสุดของพื้นที่เก็บไฟล์แคชบนดิสก์ (10GB)
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache_zone:10m inactive=60m max_size=10g;
server {
# ... (server block ของคุณ) ...
location / {
proxy_pass http://backend_servers;
# เปิดใช้งาน Cache
proxy_cache my_cache_zone; # ใช้ Cache Zone ที่กำหนดไว้
# กำหนดเวลาหมดอายุของแคช (สามารถกำหนดตาม HTTP headers จาก Backend ได้ด้วย)
proxy_cache_valid 200 302 10m; # แคช response ที่มี status 200 หรือ 302 เป็นเวลา 10 นาที
proxy_cache_valid 404 1m; # แคช response ที่มี status 404 เป็นเวลา 1 นาที
# แสดงสถานะของ Cache ใน response header (สำหรับ Debugging)
add_header X-Proxy-Cache $upstream_cache_status;
# ... (proxy_set_header และอื่นๆ) ...
}
}
}
อย่าลืมสร้างไดเรกทอรีสำหรับแคชและกำหนดสิทธิ์ให้ Nginx เข้าถึงได้ครับ