負載均衡是指在多個后端服務器之間有效地分配網絡流量。
從NGINX Plus R5[1] 版本開始可以代理和負載均衡傳輸控制協議(Transmission Control Protocol,TCP)通信。TCP是許多流行應用程序和服務的協議,如LDAP、MySQL和RTMP。
從NGINX Plus R9[2]版本開始可以代理和負載平衡UDP流量。用戶數據報協議(User Datagram Protocol,UDP)是許多流行的非事務性應用程序的協議,如DNS、syslog和RADIUS。
反向代理
基礎條件
需要使用ngx_stream_core_module模塊,該模塊從版本1.9.0開始可用。這個模塊在默認情況下是不構建的,需使用--with-stream配置參數來啟用它。如下配置:
- ./configure --prefix=/usr/local/nginx --with-stream
配置反向代理
配置反向代理,以便NGINX打開資源,將來自客戶端的TCP連接或UDP數據報轉發到upstream組或代理服務器。
A. 配置反向代理之前,看一下ngx_stream_core_module模塊中幾個元素的語法:
- stream塊,在配置文件中是***塊,和http塊屬於同一級別,語法如下:
- Syntax: stream { ... }
- Default: —
- Context: main
- server塊,配置一個服務。在***stream{}上下文中為每個虛擬服務器定義一個或多個服務器配置塊。語法如下:
- Syntax: server { ... }
- Default: —
- Context: stream
listen指令,設置服務器將接受連接的套接字的地址和端口。可以只指定端口。地址也可以是主機名,例如:
- Syntax: listen address:port [ssl] [udp] [proxy_protocol] [backlog=number] [rcvbuf=size] [sndbuf=size] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
- Default: —
- Context: server
示例如下:
- listen 127.0.0.1:12345;
- listen *:12345;
- listen 12345; # same as *:12345
- listen localhost:12345;
listen指令在此默認協議是TCP協議,對於UDP流,需要指定udp參數,如下:
- listen 12345 udp;
B. 使用ngx_stream_proxy_module模塊(默認是編譯進來的)的proxy_pass指令配置代理,proxy_pass指令語法:
- Syntax: proxy_pass address;
- Default: —
- Context: server
設置被代理服務器的地址。地址可以定義為一個域名或IP地址和一個端口號:
- proxy_pass localhost:12345;
或一個UNIX-domain socket路徑:
- proxy_pass unix:/tmp/stream.socket;
C. 如果代理服務器有多個網絡接口,可以配置NGINX使用特定的源IP地址去連接upstream服務器。這可能很有用,當一個代理服務器在nginx后面,並配置了接受來自特定IP網絡或IP地址范圍的連接。
使用ngx_stream_proxy_module模塊的proxy_bind指令,其語法:
- Syntax: proxy_bind address [transparent] | off;
- Default: —
- Context: stream, server
- #此指令在1.9.2版本中開始使用。
從指定的本地IP地址向被代理服務器發起外部連接。特殊值off取消從上層配置中繼承的proxy_bind指令產生的影響,允許系統自動分配本地IP地址。
transparent參數(1.11.0+)允許從一個非本地IP地址發起到被代理服務器的外部連接,例如從一個客戶端的真實IP地址:
- proxy_bind $remote_addr transparent;
為了使此參數起作用,通常需要使用超級用戶權限運行nginx工作進程。 在Linux上,不需要(1.13.8+),就像指定了transparent參數一樣,工作進程從主進程繼承CAP_NET_RAW功能。 還需要配置核心路由表以攔截來自被代理服務器的網絡流量。
示例配置如下:
- stream {
- # ...
- server {
- listen 127.0.0.1:12345;
- proxy_pass backend.example.com:12345;
- proxy_buffer_size 16k;
- #proxy_bind 127.0.0.1:12345;
- }
- }
負載均衡
使用ngx_stream_upstream_module模塊(默認是編譯進來的)的upstream指令。指令語法:
- Syntax: upstream name { ... }
- Default: —
- Context: stream
定義一組服務器。 服務器可以偵聽不同的端口。 此外,可以混合偵聽TCP和UNIX域套接字的服務器。
在***stream{}上下文中定義一個或多個upstream{}配置塊,並設置upstream組的名稱,例如TCP服務器的stream_backend和UDP服務器的dns_servers:
- stream {
- upstream stream_backend {
- server backend1.example.com:12345;
- server backend2.example.com:12345;
- server backend3.example.com:12346;
- }
- upstream dns_servers {
- server 192.168.136.130:53;
- server 192.168.136.131:53;
- }
- }
配置upstream組使用的負載均衡方法。 可以指定以下方法之一:
1.Round Robin:默認情況下,NGINX使用循環算法對流進行負載平衡,將其順序指向配置的upstream組中的服務器。因為它是默認方法,所以沒有round-robin指令;只需在***stream{}上下文中創建upstream{}配置塊,
2.最少連接(Least Connections)–nginx選擇當前活動連接數較少的服務器。
- Syntax: least_conn;
- Default: —
- Context: upstream
3.最少時間-NGINX Plus選擇平均延遲***且活動連接數最少的服務器。 用於計算***平均延遲的方法取決於least_time指令中包含以下哪個參數:
- Syntax: least_time connect | first_byte | last_byte [inflight];
- Default: —
- Context: upstream
A. connect - 連接upstream服務器的時間
B. first_byte - 接收數據的***個字節的時間
C. last_byte - 從服務器接收完整響應的時間,如果指定了inflight參數(1.11.6+),則還會考慮不完整的連接。
4.哈希 - NGINX根據用戶定義的key,選擇服務器。
- Syntax: hash key [consistent];
- Default: —
- Context: upstream
Hash負載平衡方法還用於配置會話持久性。 由於散列函數基於客戶端IP地址,因此來自給定客戶端的連接始終傳遞到同一服務器,除非服務器已關閉或不可用。 指定可選的consistent參數以應用ketama一致性散列方法:
- hash $remote_addr consistent;
5.random - 每個連接將傳遞給隨機選擇的服務器。 如果指定了two參數,首先,NGINX會考慮服務器權重隨機選擇兩台服務器,然后使用指定的方法選擇其中一台服務器:
Syntax: random [two [method]];Default: —Context: upstreamThis directive appeared in version 1.15.1.
A. least_conn - 活動連接數最少
B. least_time=connect - 連接上游服務器的時間($upstream_connect_time)少了美元符號
C. least_time=first_byte - 從服務器接收***個數據字節的平均時間最短($upstream_first_byte_time)
D. least_time=last_byte - 從服務器接收***一個數據字節的平均時間最短($upstream_session_time)
隨機負載平衡方法應該用於多個負載均衡器將請求傳遞到同一組后端的分布式環境.
示例:
- stream {
- upstream stream_backend {
- hash $remote_addr consistent;
- server backend1.example.com:12345 weight=5;
- server backend2.example.com:12345;
- server backend3.example.com:12346 max_conns=3;
- }
- upstream dns_servers {
- least_conn;
- server 192.168.136.130:53;
- server 192.168.136.131:53;
- }
- }
完整示例
- stream {
- upstream stream_backend {
- hash $remote_addr consistent;
- server backend1.example.com:12345 weight=5;
- server backend2.example.com:12345;
- server backend3.example.com:12346 max_conns=3;
- }
- upstream dns_servers {
- least_conn;
- server 192.168.136.130:53;
- server 192.168.136.131:53;
- }
- server {
- listen 12345;
- proxy_pass stream_backend;
- proxy_buffer_size 16k;
- #proxy_bind 127.0.0.1:12345;
- }
- server {
- listen 53 udp;
- proxy_pass dns_servers;
- proxy_buffer_size 16k;
- }
- }
結束。
[1]: https://docs.nginx.com/nginx/releases/#r5
[2]: https://docs.nginx.com/nginx/releases/#r9

