
一、Nginx的負載均衡政策
負載均衡就是将請求“均衡”地配置設定到多台業務節點伺服器上。這裡的“均衡”是依據實際場景和業務需要而定的。
對于Nginx來說,請求到達Nginx,Nginx作為反向代理伺服器,有絕對的決策權,可以按照規則将請求配置設定給它知道的節點中的一個,通過這種配置設定,使得所有節點需要處理的請求量處于相對平均的狀态,進而實作負載均衡。
Nginx支援的負載均衡政策很多,比較重點的如下:
- round robin(輪詢)
- random(随機)
- weight(權重)
- fair(按響應時長,三方插件)
- url_hash(url的hash值)
- ip_hash(ip的hash值)
- least_conn(最少連接配接數)
這麼多的政策,非常不利于記憶和選擇,我們不妨将這些常見的政策歸類,分而化之,友善挑選。
第一類 最佳實作
- weight(權重)
- random(随機)
最佳實踐,其實就是最常見、最普通的預設配置,當然也是在一定程度上最好用的配置。不知道用什麼方式的時候,就可以選擇用這一類型。
輪詢不用多說。這裡的随機,其實在大量請求的情況下,按照機率的理論等同于輪詢的方式。
輪詢配置參考:
#預設配置就是輪詢政策
upstream server_group {
server backend1.example.com;
server backend2.example.com;
}
随機配置參考:
upstream server_group {
random;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}
第二類 性能優先
- weight(權重)
- fair(按響應時長,三方插件)
- least_conn(最少連接配接數)
讓業務節點中性能更強的機器得到更多請求,這也是一個比較好的配置設定政策。什麼是性能更好的機器?這個問題也有很多的次元去考量。
- 從經驗或硬體上分為高權重、低權重的機器。
- 按照節點請求的響應時長來決定是多配置設定請求,還是少配置設定請求。
- 按照保持的連接配接數。一般來說保持的連接配接數越多說明處理的任務越多,也是最繁忙的,可以将請求配置設定給其他機器處理。
權重的配置參考:
upstream server_group {
server backend1.example.com weight=5;
#預設為不配置權重為1
server backend2.example.com;
}
響應的時長(fair)配置參考:需要在Nginx編譯時加入nginx-upstream-fair子產品。
upstream server_group{
fair;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}
最少連接配接數(least_conn)配置參考:
upstream server_group {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
第三類 保持穩定
- ip_hash
- url_hash
很多請求都是有狀态的,上一次請求到哪個業務節點,這次還要請求到哪台機器。比如常見的session就是這樣一種有狀态的業務。
這裡Nginx提供了按照用戶端ip的hash來作為使用者的标示配置設定、url的hash作為配置設定标示的規則。本質上還是要找到使用者的請求中不變的要素,抽離出來,這樣就可以進行配置設定了。
ip_hash配置參考:
upstream server_group {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
url_hash配置參考:(請求同一個資源被同一個伺服器截獲)
upstream server_group{
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}
upstream web{
hash $request_uri consistent;
server 192.168.179.100 ;
server 192.168.179.101 ;
}
[root@localhost html]# while true;do curl 192.168.179.99;sleep 1;done --可以看到每次通路固定的資源都會到固定的伺服器上去
proxy this is 192.168.179.101 page
proxy this is 192.168.179.101 page
proxy this is 192.168.179.101 page
二、Nginx支援一緻性哈希進行配置設定
Nginx支援一緻性hash進行配置設定,也就是配置中consistent。
什麼是一緻性hash?為什麼要引入這個機制?在生産環境下,業務節點經常會出現增加或減少的情況,就算這種增加或減少都是被動的,可能會對hash配置設定産生影響。如何能夠做到盡量減少影響呢?這時一緻性hash被發明出來。
一緻性hash解決兩個問題:
- 配置設定特别不均勻;
- 節點變動除了對配置設定到這個節點上的請求有影響,還會導緻其他節點上的請求重新配置設定。
1)如何解決配置設定不均的問題
将原來的每一個節點複制出N個虛拟節點,并且給這些虛拟節點都起個名字。
比如原來有5個節點,配置設定的時候經常會不均勻,現在每個節點都虛拟出N個節點,就是5*N個節點,會極大降低配置設定不均勻的情況。下面就要說說如何配置設定的問題了。
2)如何解決節點變動的問題
一緻性哈希的基本思想:
- 定義一個[0,(2^32)-1]的數值空間。相當于取長度從 0到2^32-1 的線段。節點映射到線段上。将每個節點,包括虛拟節點,都通過hash算法得到數值,然後映射到這個取值區間上。如下圖:
- 計算資料的Hash值。把請求中的關鍵字元串通過hash算法得到一個數值,線上段中找到一個位置,如果算出來的數值大于2^32-1則認為是0。按照這個規則,其實是把這個線段首尾相連形成一個環,是以也叫hash環。
- 資料節點線上段上找歸屬的節點。沿着這個線段向右找到離得最近的節點,并把該節點作為這個資料的歸屬節點。
下面再來看節點的變化對一緻性Hash的影響。
- 節點減少:比如NodeA突然故障了,原來配置設定到其他節點上的資料不會發生變化,隻有配置設定到NodeA上的資料會重新找離它們最近的點,進而減少了hash重新配置設定的數量。這也是一緻性hash最大的優勢。
- 節點增加:比如現在請求量抖增,需要增加節點降低負載。當新加入節點NodeE時,NodeE及它的一群虛拟節點會根據hash值配置設定在hash環上。這時,大部分資料再根據一緻性哈希規則找其歸屬的Node節點都不會發生變化,隻有那些值計算出來發現離NodeE更近的資料發生了變化,但數量畢竟是有限的,減少了因為節點增加造成的影響。
三、故障節點摘除與恢複
先看看經典配置,再詳細解釋。
upstream server_group {
server backend1.example.com ;
server backend2.example.com max_fails=3 fail_timeout=30s;
server backup1.example.com backup;
}
max_fails=number
這個參數決定了多少次請求後端失敗後會暫停這個業務節點,不再給它發新的請求,預設值是1。此參數需要配合fail_timeout一起用。
題外話:如何定義失敗,有很多種類型,這裡因為主要處理HTTP代理,是以更關注proxy_next_upstream。
proxy_next_upstream:主要定義了當服務節點出現狀況時,會将請求發給其他節點,也就是定義了怎麼算作業務節點失敗。
fail_timeout=time
決定了當Nginx認定這個節點不可用時,暫停多久。不配置預設就是10s。
把上面兩個參數聯合起來考慮就是:當Nginx發現發送到這個節點上的請求失敗了3次的時候,就會把這個節點摘除,摘除時間是30s,30s後才會再次發送請求到這個節點上。
backup