文章目錄
HTTP Load Balancing
將請求轉發到後端服務器
在開始使用NGINX將HTTP流量負載到一組服務器時,首先需要使用upstream
配置定義該組。配置放在http上下文中。
組中的服務器使用server指令配置(不要與定義運行在NGINX上的虛擬服務器的服務器塊混淆)。例如,下面的配置定義了一個名爲backend
的組,由三個服務器配置組成(可能在三個以上的實際服務器中解析):
http {
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
server 192.0.0.1 backup;
}
}
要將請求傳遞給服務器組,組的名稱在proxy_pass
指令中指定(或在這些協議的fastcgi_pass
、memcached_pass
、scgi_pass
或uwsgi_pass
指令中指定)。在下一個例子中,運行在NGINX上的虛擬主機將所有請求傳遞給上一個例子中定義的後端組:
server {
location / {
proxy_pass http://backend;
}
}
下面的示例結合了上面的兩個片段,並展示瞭如何將HTTP請求代理到後端服務器組。這個組由三個服務器組成,其中兩個運行同一個應用程序的實例,而第三個是備份服務器。因爲upstream
塊中沒有指定負載均衡算法,NGINX使用默認算法Round Robin
:
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
server 192.0.0.1 backup;
}
server {
location / {
proxy_pass http://backend;
}
}
}
負載均衡模式
Nginx有多種負載均衡算法:
1. Round Robin
請求均勻地分佈在各個服務器上,同時考慮了服務器的權重。默認情況下使用該方法(沒有啓用該方法的配置):
upstream backend {
# 無需配置,默認爲round robin
server backend1.example.com;
server backend2.example.com;
}
2. Least Connections
請求發送到服務器的活動連接數最少,同樣考慮到服務器權重:
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
3. IP Hash
發送請求的服務器由客戶機IP地址決定。在本例中,要麼使用IPv4地址的前三個八位計算,要麼使用整個IPv6地址來計算哈希值。該方法保證來自相同地址的請求到達相同的服務器,除非該服務器不可用
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
如果其中一臺服務器需要暫時從負載平衡中刪除,可以使用down
參數標記它,以保存當前客戶機IP地址的無法請求此服務器。將由此服務器處理的請求自動發送到組中的下一個服務器:
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
}
4. Generic Hash
發送請求的服務器由用戶定義的鍵決定,該鍵可以是文本字符串、變量或組合。例如,密鑰可以是成對的源IP地址和端口,或者是一個URI,如下例所示:
upstream backend {
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
}
哈希指令的可選一致參數支持ketama
一致哈希負載平衡。根據用戶定義的散列鍵值,請求均勻地分佈在所有upstream
服務器上。如果將上游服務器添加到或從upstream
組中刪除,則只重新映射幾個鍵,在負載平衡緩存服務器或其他累積狀態的應用程序的情況下,這些鍵可以最小化緩存丟失。
5. Random
每個請求將被傳遞到隨機選擇的服務器。
upstream backend {
random;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}
Server Weights
默認情況下,NGINX使用輪詢方法在組中的服務器之間根據它們的權重分配請求。服務器配置weight
的權值參數在service
配置中設置;默認值爲1:
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
server 192.0.0.1 backup;
}
在這個例子中,backend1.example.com
的權重爲5;其他兩臺服務器具有默認權重(1),但是IP地址爲192.0.0.1的服務器被標記爲備份服務器,除非其他兩臺服務器都不可用,否則不會接收請求。使用這種權重配置,每6個請求中就有5個發送到backend1.example.com
, 1個發送到backend2.example.com
。
TCP and UDP Load Balancing
配置反向代理
- 創建一個頂級的
stream {}
區域
stream {
# ...
}
- 在頂層
stream {}
上下文中爲每個虛擬服務器定義一個或多個server {}
配置 - 在每個服務器的
server{}
配置塊中,其中包含listen指令來定義服務器監聽的IP地址或(和)端口
stream {
server {
listen 12345;
# ...
}
server {
listen 53 udp;
# ...
}
# ...
}
- 使用proxy_pass指令來定義代理服務器或服務器轉發流量到哪一個
upstream
組
stream {
server {
listen 12345;
#TCP 數據將會被轉發到 "stream_backend" 的後端組
proxy_pass stream_backend;
}
server {
listen 12346;
#TCP 數據將會被轉發到backend.example.com:12346
proxy_pass backend.example.com:12346;
}
server {
listen 53 udp;
#UDP 數據將會被轉發到 "dns_servers" 的後端組
proxy_pass dns_servers;
}
# ...
}
- 如果代理服務器有多個網卡,您可以選擇配置NGINX綁定對應網卡,以便在連接到上游服務器時使用特定的源IP地址。
stream {
# ...
server {
listen 127.0.0.1:12345;
proxy_pass backend.example.com:12345;
# 綁定使用特定的網卡發送
proxy_bind 127.0.0.1:12345;
}
}
- NGINX可以將來自客戶機和
upstream
連接的數據放在緩存區中。如果數據量很小,可以減少緩衝區,從而節省內存資源。如果有大量數據,可以增加緩衝區大小,以減少套接字讀/寫操作的數量。
stream {
# ...
server {
listen 127.0.0.1:12345;
proxy_pass backend.example.com:12345;
# 設置緩存區大小
proxy_buffer_size 16k;
}
}
配置TCP和UDP負載均衡
- 創建一組服務器,在
stream {}
上下文中定義一個或多個upstream {}
配置塊,併爲upstream
設置名稱,例如,TCP服務器的stream_backend
和UDP服務器的dns_servers
stream {
# 需要保證stream_backend 與proxy_pass後的名字保持一致
upstream stream_backend {
# ...
}
upstream dns_servers {
# ...
}
# ...
}
- 用
upstream server
填充到upstream{}
。在upstream{}
塊中,爲每個upstream server
添加一個server指令,指定其IP地址或主機名(可以解析爲多個IP地址)和一個必需的端口號。注意,你無需爲每個服務器定義協議,因爲它是由你在前面創建的server {}
中的listen指令中包含的參數爲整個upstream
定義的
- Round Robin:默認情況下,NGINX使用循環算法來平衡流量,將流量按順序引導到已配置的上游組中的服務器(無需配置)
- Least Connections:選擇當前活動連接數量較少的服務器
- 爲upstream配置負載均衡模式
TCP和UDP負載均衡示例
stream {
upstream stream_backend {
# 選擇當前活動連接數量較少的服務器,受權重影響
least_conn;
# 權重
server backend1.example.com:12345 weight=5;
# 健康檢測 max_fails:失敗次數 fail_timeout:超時時間
server backend2.example.com:12345 max_fails=2 fail_timeout=30s;
# 最大併發連接數,默認爲0,沒有限制
server backend3.example.com:12345 max_conns=3;
}
upstream dns_servers {
least_conn;
server 192.168.136.130:53;
server 192.168.136.131:53;
server 192.168.136.132:53;
}
server {
listen 12345;
proxy_pass stream_backend;
# 與後端服務器建立連接超時
proxy_timeout 3s;
# 與後端服務器連接超時
proxy_connect_timeout 1s;
}
server {
listen 53 udp;
proxy_pass dns_servers;
}
server {
listen 12346;
proxy_pass backend4.example.com:12346;
}
}