跨多個應用程序實例的負載均衡是一種常用的技術,用於優化資源利用率、最大化吞吐量、減少延遲和容錯配置。Nginx
可以作爲一種非常有效的HTTP負載均衡器在不同的部署場景中使用。
小試牛刀
要使用Nginx
平衡一組服務器的Http請求,首先需要使用upstream
指令來定義這個組。這個指令放在http
上下文中。組中的服務器使用server
指令配置(與http
上下文中的server
不同,這是一個簡單指令)。我們在/etc/nginx/conf.d
目錄下,創建一個test.conf
文件,具體配置如下:
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
upstream backend {
server localhost:8080;
server localhost:8081;
}
server {
listen 8080;
location / {
proxy_pass http://localhost:5000;
}
}
server {
listen 8081;
location / {
proxy_pass http://localhost:5001;
}
}
上面配置中,定義了一個名爲backend
的服務器組,當有請求進來時,將會傳遞到服務器組。這個服務器組由兩個服務器組成,因爲沒有指定負載均衡算法,所以將採用輪詢算法。所以,HTTP請求將會在這兩條機器交替執行。又因爲這兩臺服務器分別代理着5000與5001端口的服務,所以請求最終會在5000和5001端口的服務交替執行!
負載均衡算法
Nginx支持4中負載均衡算法,如下:
輪詢
:請求在服務器之間平均分配,同時考慮了服務器權重(weight)。默認使用此算法,它沒有相關指令
upstream backend {
server localhost:8080;
server localhost:8081;
}
爲服務器設置權重,如下:
upstream backend {
server localhost:8080 weight=3;
server localhost:8081;
}
如此,如果有4次HTTP請求,將會有3次localhost:8080
處理,1次localhost:8081
處理
最少連接
: 選取活躍連接數與權重weight的比值最小者爲下一個處理請求的server,如果有多個server比值相等,那麼將採取加權輪詢算法。它的指令爲least_conn
,如下:
upstream backend {
least_conn;
server localhost:8080;
server localhost:8081;
}
爲服務器設置權重,如下:
upstream backend {
least_conn;
server localhost:8080 weight=2;
server localhost:8081;
}
IP哈希
:發送請求的服務器由客戶機IP地址決定。在這種情況下,使用IPv4的前三個字節或整個IPv6地址來計算哈希值。該方法保證來自相同地址的請求到達相同的服務器,除非該服務器不可用。它的指令爲ip_hash
,如下:
upstream backend {
ip_hash;
server localhost:8080;
server localhost:8081;
}
通用哈希
:請求發送到的服務器由用戶定義的鍵決定,鍵可以是文本字符串、變量或者組合。例如,祕鑰可以是成對的源IP地址或端口,或者下面例子中的uri。它的指令爲hash
,如下:
upstream backend {
hash $request_uri consistent;
server localhost:8080;
server localhost:8081;
}
hash
指令中的可選參數consistent
啓用ketama
一致性哈希負載均衡。根據用戶定義的哈希鍵值,請求均勻的分佈在所有上游服務器上。如果從上游組添加或從上游組中刪除一個上游服務器,則只會重新映射幾個鍵,這在負載均衡中緩存服務器或其他積累狀態的應用程序中最小化了緩存丟失。
server參數
backup
:設置服務器爲備份服務器,當其他服務器沒有空閒時,將由備份服務器執行
upstream backend {
server localhost:8080 backup;
server localhost:8081;
}
down
:如果一個服務器需要暫時從負載均衡循環中移除,可以使用down
參數來標記它,以保持當前客戶端IP地址的哈希。本服務器的請求將自動發送到組中的下一個服務器,如下:
upstream backend {
server localhost:8080 down;
server localhost:8081;
}
fail_timeout
:在這個時間內,通信失敗的嘗試數量達到指定次數時,認爲服務器不可用。默認情況下,該參數設置爲10秒鐘
upstream backend {
server localhost:8080 max_fails=5 fail_timeout=30s;
server localhost:8081;
}
max_conns
:限制代理服務器的最大併發活動的連接數。默認值爲0,表示沒有限制。如果服務器組不駐留在共享內存中,則限制對每個工作進程都有效。
upstream backend {
server localhost:8080 max_conns=10;
server localhost:8081;
}
max_fails
:在指定時間內,通信失敗的最大嘗試數量。默認情況下,該參數設置爲1。設置爲0表示禁止嘗試次數的記錄
upstream backend {
server localhost:8080 max_fails=5;
server localhost:8081;
}
resolve
:監視與服務器域名相對應的IP地址的更改,並自動修改上游配置,而無需重新啓動Nginx
。服務器組必須駐留在共享內存當中。爲了使此參數起作用,必須在http
塊中指定resolver
指令。例如:
http {
resolver 10.0.0.1 valid=300s ipv6=off;
resolver_timeout 10s;
server {
location / {
proxy_pass http://backend;
}
}
upstream backend {
zone backend 32k;
least_conn;
server backend1.example.com resolve;
server backend2.example.com resolve;
}
}
在這個例子當中,server
指令中的resolve
參數告訴Nginx
定期將backend1.example.com
和backend2.example.com
域名重新解析爲IP地址。
resolver
指定定義了Nginx
發送請求的DNS服務器的IP地址(這裏是10.0.0.1)。默認情況下,Nginx
會按照生存時間(TTL)在記錄中指定的頻率重新解析DNS記錄,但是你可以使用有效參數覆蓋TTL值;在本例中是300秒,即5分鐘。可選參數ipv6=off
表示僅IPv4地址用於負載均衡,儘管默認情況下支持同時解析IPv4和IPv6地址。
如果域名解析爲多個IP地址,則這些地址將保存到上游配置並進行負載均衡。在我們的示例當中,服務器使用least_conn
的負載均衡算法進行負載均衡。如果服務器的IP地址發生了改變,Nginx
將立即開始在新的地址集之間進行負載均衡。
route
:設置服務器路由名稱
upstream backend {
server localhost:8080 route=a;
server localhost:8081 route=b;
}
slow_start
: 服務器慢啓動功能能防止剛剛恢復的服務器被大量連接超載導致服務器超時又被標爲失敗。在Nginx
中,慢啓動能讓上流服務器在完全恢復並可用之後逐漸把它的權重從0恢復到設置的值,這可以通過僞指令參數slow_start
來實現:
upstream backend {
server localhost:8080 slow_start=30s;
server localhost:8081;
}
這個時間值設置了服務器恢復權重的時間。
weight
:設置服務器權重,默認爲1
upstream backend {
server localhost:8080 weight=2;
server localhost:8081;
}
值得注意的是,如果服務器組中只有一個服務器,那麼server
指令中的max_fails
、fail_timeout
和slow_start
參數將被忽略,服務器永遠不會被認爲不可用!