Nginx เป็นที่รู้จักกันดีในการทำหน้าที่เป็น HTTP/HTTPS reverse proxy สำหรับเว็บแอปพลิเคชัน แต่คุณสมบัติอันทรงพลังที่มักถูกมองข้ามคือ Stream Module ซึ่งช่วยให้ Nginx สามารถทำ Load Balancing สำหรับ TCP/UDP protocols ได้ Stream Module ช่วยให้คุณสามารถสร้าง proxy สำหรับฐานข้อมูล (MySQL, PostgreSQL) บริการ Redis และแอปพลิเคชันอื่น ๆ ที่ไม่ใช่ HTTP
บทความนี้จะอธิบายรายละเอียดเกี่ยวกับวิธีการใช้งาน Stream Module ใน Nginx สำหรับ Load Balancing ขั้นสูง รวมถึงตัวอย่างการใช้งานจริง การตั้งค่า และเทคนิคการจัดการการเชื่อมต่อ
Stream Module คืออะไร? Layer 4 vs Layer 7
Stream Module เป็นโมดูลของ Nginx ที่ทำให้สามารถทำ proxy สำหรับการเชื่อมต่อ Transport Layer (Layer 4) ของ OSI Model ซึ่งแตกต่างจากการทำ proxy แบบดั้งเดิมของ Nginx (http module) ที่ทำงานที่ Application Layer (Layer 7)
ความแตกต่างระหว่าง Layer 4 และ Layer 7
| ลักษณะ | Layer 4 (Transport) | Layer 7 (Application) |
|---|---|---|
| โปรโตคอล | TCP, UDP | HTTP, HTTPS, FTP |
| ความสามารถในการตัดสินใจ | ขึ้นอยู่กับ IP, Port เท่านั้น | ขึ้นอยู่กับ Host, Path, Headers |
| ความเร็ว | เร็วกว่า (ไม่ต้องวิเคราะห์เนื้อหา) | ช้ากว่า (ต้องวิเคราะห์เนื้อหา) |
| การใช้งาน | ฐานข้อมูล, DNS, เมล, Redis | เว็บไซต์, API, บริการ HTTP |
| Module ใน Nginx | Stream Module | HTTP Module |
การเปิดใช้งาน Stream Module ใน Nginx
เมื่อติดตั้ง Nginx หากต้องการใช้ Stream Module จะต้องรวมคำสั่ง --with-stream ระหว่างการ compile ให้ตรวจสอบว่าเปิดใช้งาน Stream Module อยู่แล้วด้วยคำสั่ง:
nginx -V 2>&1 | grep stream
หากผลลัพธ์แสดง --with-stream หมายความว่า Stream Module ถูกเปิดใช้งานแล้ว
หากต้องการเปิดใช้งาน ให้ compile Nginx โดยเพิ่มคำสั่ง:
./configure --with-stream --with-stream-ssl_module
make
make install
โครงสร้างไฟล์ Stream Configuration
Stream configuration อยู่นอก http block และโดยปกติจะอยู่ที่ /etc/nginx/nginx.conf ตัวอย่างโครงสร้างพื้นฐาน:
# ไฟล์ /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
# HTTP block สำหรับเว็บไซต์ปกติ
http {
include /etc/nginx/conf.d/*.conf;
}
# STREAM block สำหรับ TCP/UDP proxy
stream {
upstream mysql_backend {
server 192.168.1.10:3306 max_fails=2 fail_timeout=10s;
server 192.168.1.11:3306 max_fails=2 fail_timeout=10s;
}
server {
listen 3306;
proxy_pass mysql_backend;
}
}
Stream Block Configuration
Stream block คือหน่วยการกำหนดค่าของ Stream Module ที่ใช้ในการ proxy TCP/UDP connections
โครงสร้างพื้นฐาน
stream {
# Upstream สำหรับ backend servers
upstream backend_servers {
server backend1.example.com:5432;
server backend2.example.com:5432;
server backend3.example.com:5432;
}
# Server block ที่ listen บน port ใดเพื่อ proxy ไป upstream
server {
listen 5432 tcp; # TCP port
listen [::]:5432 tcp; # IPv6 support
proxy_pass backend_servers;
proxy_connect_timeout 1s;
}
}
TCP Load Balancing สำหรับฐานข้อมูล
TCP Load Balancing นิยมใช้สำหรับ proxy คำขอไปยังฐานข้อมูลต่าง ๆ เช่น MySQL, PostgreSQL โดย Nginx จะกระจายการเชื่อมต่อไปยัง backend servers
ตัวอย่าง: MySQL Load Balancing
stream {
upstream mysql_cluster {
least_conn; # Load balancing algorithm
server 10.0.1.10:3306 weight=5;
server 10.0.1.11:3306 weight=3;
server 10.0.1.12:3306 weight=2;
}
server {
listen 3306;
listen [::]:3306;
proxy_pass mysql_cluster;
proxy_buffer_size 16k;
proxy_connect_timeout 3s;
proxy_timeout 60s;
}
}
ตัวอย่าง: PostgreSQL Load Balancing
stream {
upstream postgres_cluster {
hash $remote_addr; # Connection hashing
server db1.internal:5432;
server db2.internal:5432;
server db3.internal:5432;
}
server {
listen 5432;
proxy_pass postgres_cluster;
proxy_connect_timeout 5s;
proxy_timeout 30m; # Long timeout สำหรับ long-running queries
}
}
ตัวอย่าง: Redis Load Balancing
stream {
upstream redis_nodes {
least_conn;
server redis1:6379;
server redis2:6379;
server redis3:6379;
}
server {
listen 6379;
proxy_pass redis_nodes;
proxy_buffer_size 32k;
proxy_connect_timeout 2s;
}
}
UDP Load Balancing สำหรับบริการ DNS และ Syslog
Stream Module รองรับ UDP ซึ่งสำคัญสำหรับบริการที่ใช้ UDP เช่น DNS, Syslog
ตัวอย่าง: DNS Load Balancing
stream {
upstream dns_backend {
least_conn;
server ns1.example.com:53;
server ns2.example.com:53;
server ns3.example.com:53;
}
server {
listen 53 udp reuseport;
listen [::]:53 udp reuseport;
proxy_pass dns_backend;
proxy_response_timeout 30s;
proxy_timeout 30s;
}
}
ตัวอย่าง: Syslog Load Balancing
stream {
upstream syslog_servers {
hash $remote_addr;
server syslog1:514;
server syslog2:514;
server syslog3:514;
}
server {
listen 514 udp reuseport;
proxy_pass syslog_servers;
proxy_responses 1;
proxy_timeout 20s;
}
}
Load Balancing Algorithms ใน Stream Module
Stream Module รองรับหลายวิธีการกระจายการเชื่อมต่อ (load balancing algorithms)
1. Round-Robin (Default)
ใช้เวลารอบของเซิร์ฟเวอร์ โดยคำนึงถึง weight
upstream backend {
server server1:5432;
server server2:5432;
server server3:5432;
}
2. Least Connections
เลือกเซิร์ฟเวอร์ที่มีการเชื่อมต่อน้อยที่สุด เหมาะสำหรับ long-lived connections
upstream backend {
least_conn;
server server1:5432;
server server2:5432;
server server3:5432;
}
3. Hash
ใช้ hash ของตัวแปรในการเลือกเซิร์ฟเวอร์ เพื่อให้ client เดียวกันไปยัง server เดียวกันเสมอ
upstream backend {
hash $remote_addr; # Hash based on client IP
server server1:5432;
server server2:5432;
server server3:5432;
}
4. Random
สุ่มเลือกเซิร์ฟเวอร์ โดยอาจใช้ two-choice algorithm
upstream backend {
random two least_conn;
server server1:5432;
server server2:5432;
server server3:5432;
}
Health Checks สำหรับ TCP/UDP Backends
Nginx สามารถตรวจสอบสถานะของ backend servers และตัดออกจาก rotation หากเซิร์ฟเวอร์ลง
stream {
upstream healthy_backend {
server server1:5432 max_fails=3 fail_timeout=30s;
server server2:5432 max_fails=3 fail_timeout=30s;
server server3:5432 max_fails=3 fail_timeout=30s;
}
server {
listen 5432;
proxy_pass healthy_backend;
proxy_connect_timeout 5s;
}
}
พารามิเตอร์:
- max_fails: จำนวนครั้งที่ล้มเหลวก่อนที่จะถือว่า server ลง
- fail_timeout: ระยะเวลาที่จะพิจารณาว่า server ลง
SSL/TLS Termination และ SSL Passthrough
SSL/TLS Termination
Nginx ทำ SSL/TLS decryption และ encrypt ใหม่เมื่อ proxy ไปยัง backend
stream {
upstream mysql_backend {
server 10.0.1.10:3306;
server 10.0.1.11:3306;
}
server {
listen 3306 ssl;
proxy_pass mysql_backend;
# SSL certificates
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
}
}
SSL Passthrough (Transparent SSL Proxy)
ใช้ ssl_preread module เพื่อ proxy SSL traffic โดยไม่ decrypt
stream {
upstream ssl_backend {
server backend1:443;
server backend2:443;
server backend3:443;
}
map $ssl_preread_server_name $upstream {
backend1.example.com backend1;
backend2.example.com backend2;
backend3.example.com backend3;
default ssl_backend;
}
server {
listen 443;
listen [::]:443;
ssl_preread on;
proxy_pass $upstream;
}
}
Access Control ใน Stream Module
ใช้ allow/deny directives เพื่อควบคุมว่า IP ใดสามารถเชื่อมต่อได้
stream {
upstream database {
server db1:5432;
server db2:5432;
}
server {
listen 5432;
# Allow specific subnets
allow 10.0.0.0/8;
allow 172.16.0.0/12;
# Deny all others
deny all;
proxy_pass database;
}
}
Stream Logging
Stream module มี logging capability ที่ช่วยในการ debug และ monitoring
stream {
# กำหนด log format
log_format stream_log '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
access_log /var/log/nginx/stream_access.log stream_log;
upstream backend {
server backend1:5432;
server backend2:5432;
}
server {
listen 5432;
proxy_pass backend;
# Connection logging
access_log /var/log/nginx/db_connections.log stream_log;
}
}
Stream กับ Map Directive
ใช้ map เพื่อ dynamic routing ตามเงื่อนไขต่าง ๆ
stream {
upstream primary_db {
server 10.0.1.10:5432;
}
upstream replica_db {
server 10.0.1.20:5432;
}
# Route based on source IP or port
map $remote_port $backend_pool {
~^3[0-9]{4}$ primary_db; # Ports 30000-39999 -> primary
default replica_db; # Others -> replica
}
server {
listen 5432;
proxy_pass $backend_pool;
}
}
Proxy Protocol Support
ใช้ PROXY protocol เพื่อส่งข้อมูล client IP ไปยัง backend
stream {
upstream backend {
server backend1:5432;
server backend2:5432;
}
server {
listen 5432;
proxy_pass backend;
# Send PROXY protocol v1
proxy_protocol on;
}
}
Connection Limiting
จำกัดจำนวนการเชื่อมต่อจากแต่ละ client เพื่อป้องกัน DoS
stream {
limit_conn_zone $remote_addr zone=stream_limit:10m;
upstream backend {
server backend1:5432;
server backend2:5432;
}
server {
listen 5432;
# Limit to 10 connections per IP
limit_conn stream_limit 10;
proxy_pass backend;
}
}
ตัวอย่างการใช้งานจริง
ตัวอย่าง 1: Database Proxy สำหรับ MySQL Cluster
stream {
upstream mysql_cluster {
least_conn;
# Primary server
server 10.0.1.10:3306 weight=5 max_fails=2 fail_timeout=10s;
# Secondary servers
server 10.0.1.11:3306 weight=3 max_fails=2 fail_timeout=10s;
server 10.0.1.12:3306 weight=2 max_fails=2 fail_timeout=10s;
}
server {
listen 3306;
listen [::]:3306;
proxy_pass mysql_cluster;
proxy_buffer_size 16k;
proxy_connect_timeout 3s;
proxy_timeout 60s;
# Access control
allow 10.0.0.0/8;
deny all;
# Logging
access_log /var/log/nginx/mysql.log;
}
}
ตัวอย่าง 2: DNS Load Balancer
stream {
upstream dns_servers {
least_conn;
server 8.8.8.8:53;
server 8.8.4.4:53;
server 1.1.1.1:53;
}
server {
listen 53 udp reuseport;
listen 53 tcp reuseport;
listen [::]:53 udp reuseport;
listen [::]:53 tcp reuseport;
proxy_pass dns_servers;
proxy_timeout 20s;
proxy_responses 1;
}
}
ตัวอย่าง 3: Mail Proxy (SMTP/POP3)
stream {
upstream mail_backend {
hash $remote_addr;
server mail1.internal:25;
server mail2.internal:25;
server mail3.internal:25;
}
server {
listen 25;
listen 587;
listen [::]:25;
listen [::]:587;
proxy_pass mail_backend;
proxy_timeout 30m;
proxy_connect_timeout 5s;
}
}
Best Practices สำหรับ Stream Module
- ตั้งค่า timeout อย่างเหมาะสม – ให้ความสำคัญกับการตั้งค่า proxy_timeout ตามชนิดของบริการ
- ใช้ health checks – เพื่อให้ Nginx รู้ว่า backend ใดที่อยู่ในสภาพดี
- เปิดใช้ access logging – เพื่อติดตามการใช้งานและ debug ปัญหา
- ใช้ SSL/TLS – เมื่อส่งข้อมูลสำคัญ
- ตั้งค่า limit_conn – เพื่อป้องกัน DoS attacks
- กำหนด buffer size ให้เหมาะสม – ขึ้นอยู่กับขนาดของข้อมูลที่ส่ง
สรุป
Nginx Stream Module เป็นเครื่องมือที่ทรงพลังสำหรับ Layer 4 load balancing ที่อนุญาตให้คุณ proxy TCP/UDP connections ได้อย่างมีประสิทธิภาพ ไม่ว่าจะเป็น database proxy, DNS load balancer, หรือ mail server proxy
การใช้ Stream Module ให้ได้ประสิทธิภาพสูงสุดต้องเข้าใจเกี่ยวกับ load balancing algorithms, health checks, SSL/TLS configuration, และ access control ด้วย ด้วยการกำหนดค่าที่ถูกต้อง คุณสามารถสร้าง infrastructure ที่มีความน่าเชื่อถือสูงและมีความสามารถในการทำงานได้เต็มที่
แนะนำบริการ DE Cloud VPS และ Cloud Hosting
หากคุณต้องการบริการ Cloud infrastructure ที่ช่วยให้คุณสามารถใช้งาน Nginx Stream Module ได้อย่างเต็มประสิทธิภาพ Dot Enterprise (DE) เสนอโซลูชันที่เหมาะสำหรับการ deploy Nginx load balancer
DE Cloud VPS
DE Cloud VPS https://de.co.th/cloud-vps เป็นบริการ Virtual Private Server ที่ให้ control เต็มที่ในการติดตั้งและกำหนดค่า Nginx ตามความต้องการของคุณ ด้วยการใช้ Cloud VPS คุณสามารถ:
- ติดตั้ง Nginx ด้วย Stream Module สำหรับ TCP/UDP load balancing
- ควบคุม firewall และ access control เพื่อรักษาความปลอดภัย
- ปรับขนาด resources เมื่อการใช้งานเพิ่มขึ้น
- ตั้งค่า multiple IPs สำหรับ SSL certificates หลายตัว
DE Cloud Hosting
DE Cloud Hosting https://de.co.th/cloud-hosting เหมาะสำหรับผู้ที่ต้องการบริการที่ managed มากขึ้น โดย DE จะจัดการเรื่อง infrastructure, updates, และ security patches ให้คุณ
- การ setup Nginx ด้วย Stream Module ถูกจัดการโดยทีมเทคนิคของ DE
- Automatic backups และ disaster recovery
- 24/7 technical support จากทีมผู้เชี่ยวชาญ
- Scalable infrastructure ที่ปรับตัวตามความต้องการของแอปพลิเคชัน
สำหรับการสัมปชัญเรื่อง setup Nginx Stream Module สำหรับ production environment โปรดติดต่อ DE เพื่อขอคำปรึกษาจากทีมผู้เชี่ยวชาญ

