Nginx之負載均衡配置(一)
- 2020 年 3 月 12 日
- 筆記
前文我們聊了下nginx作為反向代理伺服器,代理後端動態應用伺服器的配置,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/12430543.html;今天我們來聊一聊nginx作為反向代理伺服器,代理一組伺服器的配置(負載均衡);前邊我們只說到了nginx怎麼去代理後端伺服器響應客戶端的請求,它在響應客戶端請求的流程是這樣的,用戶請求發送到nginx代理伺服器上,此時nginx伺服器扮演的就是服務端的角色,客戶端是無法感知後端伺服器的存在,而用戶的報文被nginx接收後,nginx代理伺服器它會把用戶的請求報文拆開看,用戶請求的資源,然後把用戶的請求資源,拿到自己的location中進行匹配,如果匹配到了,就按照匹配到的location中定義的代理規則進行代理,在這之前nginx首先會看自己的快取是否存在用戶請求的資源,如果有,它就從快取中響應用戶,如果沒有,它就扮演客戶端的角色,重新對用戶請求重新封裝請求報文,發送給後端伺服器,後端伺服器收到請求後,把對應資源響應給nginx代理伺服器,nginx會把後端伺服器響應的資源,先快取一份(如果允許快取的話),然後在封裝響應報文,響應客戶端;從這樣一個過程來看,nginx它既當伺服器角色,又當客戶端角色,而且nginx是可以把用戶的報文拆開,然後再封裝;這是nginx作為代理伺服器代理後端伺服器響應客戶端請求的一個過程(後端伺服器是一個的情況);如果後端伺服器有多個,都是提供者相同的服務,此時我們該怎麼把客戶端的請求代理到後端多台伺服器呢?
首先我們來了解下nginx的upstream模組,nginx的upstream模組有兩個,一個是基於http協議的upstream,它主要是基於http協議定義後端伺服器組,還有一個就是基於tcp協議的upstream,它主要是基於tcp協議定義後端伺服器組;我們先說nginx的http里的upstream模組吧!!!
一、ngx_http_upstream_module:此模組用於定義一組伺服器,然後被proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass和memcached_pass指令引用的伺服器組。意思很簡單,就是把相同的多台伺服器歸併成一組伺服器,然後nginx基於各種協議的代理,把請求代理到該組上,從而實現把用戶請求代理到後端多台伺服器上
1、upstream name {……}:此指令只能用於http配置段中,意思是定義一組後端伺服器組;
2、server address [parameters]:此指令用於upstream配置段中,表示定義upstream配置段中的server成員,以及相關的參數;其中地址的格式支援IP地址加埠的形式,支援unix path路徑,也支援主機名或域名加埠的形式;parameters表示參數,常用的參數有weight=number權重,默認是1,max_fails=number表示失敗嘗試最大次數;超出此處指定的次數,nginx將失敗的server標記為不可用;fail_timeout=time表示設置將伺服器標記為不可用狀態的超時時長;max_conns表示當前的伺服器的最大並發連接數;backup表示將伺服器標記為“備用”,既所有伺服器均不可用時,此伺服器才會被啟用,有點類似LVS里的sorry server的角色;down表示將伺服器標記為“不可用”
3、least_conn:此指令表示最少連接調度演算法,當server擁有不同的權重時表示wlc演算法
4、ip_hash:此指令類似lvs里的sh演算法(源地址哈希演算法),同一客戶端地址始終調度到同一台伺服器上;
5、hash key [consistent]:基於指定的key的hash表示實現對請求的調度,此處的key可以是文本、變數、或者二者的組合;作用是將請求分類,將同一類請求發往同一個upstream的server進行響應;
6、keepalive connections:為每個worker進程保留的空閑的長連接數量;
示例:
定義一組伺服器名為webserver
提示:upstream 只能用於定義在http配置段中,它表示定義一組伺服器,名為webserver ,後續調度直接將用戶請求代理到該組上即可;
提示:以上配置表示將用戶訪問www.proxy.com時將用戶請求代理到webserver這個組上的伺服器,默認情況下是輪詢的;
提示:可以看到客戶端的請求是可以通過nginx把請求代理到後端一組伺服器上,從上面的響應結果來看,我們不配置任何權重,它默認就是輪詢的(當然上面的結果也有重複的,這個還不太清楚為什麼會重複,可能是每個報文的響應速度不一樣吧,但總的響應是一樣的每個後端伺服器各佔一半);當然我們也是可以給不同的伺服器加上不同的權重,此時nginx作為調度器就是使用的加權輪詢,如下配置
提示:以上配置表示 192.168.0.20這台伺服器的權重是5,0.22的權重是2,意思就是7個請求中,0.20處理5個請求,0.22處理2個請求;
假如我們後端伺服器有一台服務出現故障,nginx會不會把用戶的請求調度到出現故障的伺服器上呢?我們知道在lvs做調度器時,前端lvs會把用戶的請求調度到出現故障的伺服器上,我們需要藉助keepalived或者其他輔助服務去實現對後端伺服器做健康狀態監測,才能把用戶的請求不調度到有故障的後端伺服器上,nginx會不會呢?
提示:可以看到nginx不會把用戶的請求調度到有故障的伺服器上,這是因為nginx自身就有對後端伺服器做健康狀態監測的機制,能夠及時的發現後端伺服器的健康狀態,及時的將服務不可用的後端主機從集群中下線,當然這種下線是當服務不可用時,自動觸發的動作,我們也可以人為的把後端伺服器標記為不可用狀態,通常在做灰度發布時可能用到,直接在伺服器後面明確用down來標記該伺服器,不接受任何請求;
提示:以上配置表示把0.22這台主機從webserver組中下線,下線的意思就是不再往上調度請求;當然此時的組中伺服器就只用0.20這一台主機,用戶請求也只能調度到這台上,所以用戶不管怎麼請求,nginx都只會把請求調度到0.20這台後端主機上;
假如後面的兩台主機都宕機了,此時用戶訪問我們的網站會不會像lvs那樣,有sorry server 來給用戶說sorry 呢?
提示:可以看到當後端主機全部宕機後,沒有像lvs里的有sorry server出來給用戶說sorry 或者響應客戶端請求的;在nginx里sorry server里的配置很簡單,只需要在伺服器的後面打上backup的標籤即可
提示:以上配置表示把127.0.0.1:80作為sorry server ,意思是組裡的正常被代理的主機全部宕機後,這台主機才會被調度,當組裡主機有一台恢復正常,這台主機就不被調度,用戶請求將調度到正常的那一台主機上;
提示:可以看到當後端主機全部宕機後,sorry server就會被調度;
提示:當後端主機恢復時,sorry server 就不會被調度,用戶的請求將會被代理至恢復的那台主機上;
以上就是nginx作為負載均衡的常用配置,接下來我們在說說調度演算法
基於源地址hash演算法
提示:以上配置表示同一源地址的客戶端請求將會調度到後端某一台server上進行響應
提示:可以看到同一客戶段始終被調度到一台server上進行響應,這種就叫做源地址綁定;除了以上ip_hash;來指定綁定源地址,還可以通過hash key來指定,以上配置等同hash $remote_addr;
基於用戶請求的uri進行綁定,用戶請求同一uri始終調度到某一server上響應,這樣做的好處可以使快取命中提高;
提示:以上配置表示綁定用戶請求的rui,不同的用戶請求同一rui時,nginx會始終把同一rui的請求調度到同一台server上進行響應;
提示:可以看到同一客戶端請求不同的uri時,會根據請求的uri隨機調度到某一台server上進行響應;從上面的配置實例我們可以知道我們把什麼當作key來hash,就可以實現基於什麼來綁定後端伺服器,比如基於用戶請求的uri當作hash對象,那麼用戶請求同一uri就會被調度到同一server上進行響應,如果基於用戶源ip地址當作hash對象,那麼同一源IP地址的用戶,不論請求什麼uri都會被調度到同一server進行響應;按這個邏輯我們可以綁定用戶的資訊來做調度;
以上就是nginx作為七層代理http請求的負載均衡的常用配置;總結一點nginx作為負載均衡使用其中核心的思想就是把同類服務的伺服器先歸併到一個組裡,然後基於不同協議的代理來把用戶的請求反代到該組上,然後基於某種調度演算法來實現把用戶請求調度到某一台server進行響應;