- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Nginx的負載均衡是什么
本篇內容介紹了“Nginx的是什么”的有關(guān)知識,在實(shí)際案例的操作過(guò)程中,不少人都會(huì )遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學(xué)有所成!
負載均衡
所謂負載均衡,就是 Nginx 把請求均勻的分攤給上游的應用,這樣即使某一個(gè)服務(wù)器宕機也不會(huì )影響請求的處理,或者當應用服務(wù)器扛不住了,可以隨時(shí)進(jìn)行擴容。
Nginx 在 AKF 可擴展立方體上的應用
在 x 軸上,可以通過(guò)橫向擴展應用服務(wù)器集群,Nginx 基于 Round-Robin 或者 Least-Connected 算法分發(fā)請求。但是橫向擴展并不能解決所有問(wèn)題,當數據量大的情況下,無(wú)論擴展多少臺服務(wù),單臺服務(wù)器數據量依然很大。
在 y 軸上,可以基于 URL 進(jìn)行不同功能的分發(fā)。需要對 Nginx 基于 URL 進(jìn)行 location 的配置,成本較高。
在 z 軸上可以基于用戶(hù)信息進(jìn)行擴展。例如將用戶(hù) IP 地址或者其他信息映射到某個(gè)特定的服務(wù)或者集群上去。
這就是 Nginx 的負載均衡功能,它的主要目的就是為了增強服務(wù)的處理能力和容災能力。
反向代理
反向代理和負載均衡在某種程度上是密不可分的。
Nginx 支持多種協(xié)議的反向代理。四層的反向代理比較簡(jiǎn)單,無(wú)論是 UDP 還是 TCP 的流量過(guò)來(lái),轉發(fā)到上游的依然是 UDP 或 TCP 的流量。
而到了應用層時(shí),就不太相同了,因為 HTTP 的 Header 中包含了大量的業(yè)務(wù)信息,需要根據 HTTP 的頭部轉換成不同的協(xié)議。
反向代理與緩存
緩存這個(gè)問(wèn)題分為兩類(lèi),一類(lèi)是時(shí)間緩存,一類(lèi)是空間緩存。
時(shí)間緩存是指,當用戶(hù)請求一個(gè)頁(yè)面的時(shí)候,Nginx 發(fā)現沒(méi)有緩存,就會(huì )到后端服務(wù)器去取,在返回給用戶(hù)響應的同時(shí)還會(huì )緩存一份,這樣當下一個(gè)用戶(hù)去請求的時(shí)候就會(huì )直接用緩存作為響應而不會(huì )再去請求上游的服務(wù)器。
空間緩存這種用的比較少,主要是指當用戶(hù)發(fā)來(lái)請求的時(shí)候,Nginx 可以提前去上游服務(wù)器獲取一些響應的內容,這個(gè)后面可以看到是怎么用的。
upstream 與 server 指令
指令name 表示負載均衡集群的名字,而 {} 內指定了一系列的服務(wù)器server 后跟服務(wù)器地址,地址后還可以加一些參數 parameters
Syntax: upstream name { ... } Default: — Context: http Syntax: server address [parameters]; Default: — Context: upstream
功能:指定一組上游服務(wù)器地址,地址可以是域名、IP 地址或者 Unix Socket 地址??梢栽谟蛎蛘?IP 地址后加端口,如果不加端口,那么默認使用 80 端口。
通用參數:server 后可以添加的參數backup:指定當前 server 為備份服務(wù),僅當非備份 server 不可用時(shí),請求才會(huì )轉發(fā)到該 server表示某臺服務(wù)已經(jīng)下線(xiàn),不再服務(wù)
負載均衡算法
加權 Round-Robin 負載均衡算法
Round-Robin(rr) 負載均衡算法發(fā)給上游服務(wù)器的請求是輪詢(xún)發(fā)送的,相當于所有上游服務(wù)器根據順序依次處理發(fā)來(lái)的請求。
有些情況下上游服務(wù)器性能不同,比如 4C8G 和 8C16G 的服務(wù)器都有,那么這時(shí)候就可以對服務(wù)器設置一些權重,讓性能好的承擔更多的請求。
功能在加權輪詢(xún)的方式訪(fǎng)問(wèn) server 指令指定的上游服務(wù)集成在 Nginx 的 upstream 框架中,無(wú)法移除
指令weight:服務(wù)訪(fǎng)問(wèn)的權重,默認是 1max_conns:server 的最大并發(fā)連接數,僅作用于單 worker 進(jìn)程。默認是 0,表示沒(méi)有限制max_fails:在 fail_timeout 時(shí)間段內,最大的失敗次數。當達到最大失敗時(shí),會(huì )在 fail_timeout 秒內這臺 server 不允許再次被選擇fail_timeout:?jiǎn)挝皇敲?,默認 10 秒,可以指定一段時(shí)間內最大失敗次數 max_fails 以及到達 max_fails 之后該 server 不能訪(fǎng)問(wèn)的時(shí)間
對上游服務(wù)使用 keepalive 長(cháng)連接
Nginx 與上游服務(wù)一般是在內網(wǎng)中的,所以開(kāi)啟 keepalive 后效果后更明顯。
功能:通過(guò)復用連接,降低 Nginx 與上游服務(wù)器建立、關(guān)閉連接的消耗,提升吞吐量的同時(shí)降低時(shí)延
模塊: ngx_http_upstream_keepalive_module 默認編譯進(jìn) Nginx,通過(guò) --without-http_upstream_keepalive_module 移除
對上游服務(wù)器的 HTTP 頭部設定
Syntax: keepalive connections; Default: — Context: upstream # 1.15.3 非穩定版本新增命令 Syntax: keepalive_requests number; Default: keepalive_requests 100; Context: upstream Syntax: keepalive_timeout timeout; Default: keepalive_timeout 60s; Context: upstream keepalive connections;
指定上游服務(wù)域名解析的 resolver 指令
當使用域名訪(fǎng)問(wèn)上游服務(wù)時(shí),可以指定一個(gè) 解析的地址,還可以設置超時(shí)等,這個(gè)時(shí)候就要用到 resolver 指令。
Syntax: resolver address ... [valid=time] [ipv6=on|off]; Default: — Context: http, server, location Syntax: resolver_timeout time; Default: resolver_timeout 30s; Context: http, server, location
實(shí)戰
下面我起了兩個(gè) Nginx 的進(jìn)程,一個(gè)作為上游服務(wù)器,監聽(tīng) 8011 和 8012 端口,另一個(gè)作為反向代理向上游服務(wù)器發(fā)請求。
上游服務(wù)器的配置如下,當請求是到達 8011 端口就返回 8011 server response. ,當請求到達 8012 端口返回 8012 server response. 。
server { listen 8011; default_type text/plain; return 200 '8011 server response.\n'; } server { listen 8012; default_type text/plain; # client_body_in_single_buffer on; return 200 '8012 server response.\n'; }
作為反向代理的 Nginx 服務(wù)器配置是這個(gè)樣子的:
這里面 8011 端口和 8012 端口的區別在于 8011 端口設置了權重和對應的參數。
upstream rrups { server 127.0.0.1:8011 weight=2 max_conns=2 max_fails=2 fail_timeout=5; server 127.0.0.1:8012; keepalive 32; } server { server_name rrups.ziyang.com; error_log myerror.log info; location /{ proxy_pass http://rrups; proxy_http_version 1.1; proxy_set_header Connection ""; } }
兩個(gè) Nginx 都配置好之后,來(lái)測試一下:
? nginx curl rrups.ziyang.com 8011 server response. ? nginx curl rrups.ziyang.com 8011 server response. ? nginx curl rrups.ziyang.com 8012 server response.
由于 8011 端口的權重設置的是 2,所以根據 rr 算法,每次都是先兩個(gè)連接負載到 8011 端口上然后是 8012 端口。
這一節講了 rr 負載均衡算法,rr 算法是所有負載均衡算法的基礎,在其他負載均衡算法失效的情況下,Nginx 也會(huì )使用 rr 算法進(jìn)行負載均衡。
負載均衡哈希算法,ip_hash 與 hash 模塊
rr 輪詢(xún)算法沒(méi)有辦法保證請求由某一臺指定的服務(wù)器去處理,只能輪詢(xún)處理請求,在 AKF 立方體中只能在 x 軸方向上進(jìn)行水平擴展。如果基于 z 軸擴展,就可以采用哈希算法保證某一類(lèi)請求只由特定的服務(wù)器處理。
功能:以客戶(hù)端的 IP 地址作為 hash 算法的關(guān)鍵字,映射到特定的上游服務(wù)器中對 IPv4 地址使用前 3 個(gè)字節作為關(guān)鍵字,對 IPv6 則使用完整地址可以使用 rr 算法的參數可以基于 realip 模塊修改用于執行算法的 IP 地址
模塊: ngx_http_upstream_ip_hash_module ,通過(guò) --without-http_upstream_ip_hash_module 禁用模塊
指令的話(huà)比較簡(jiǎn)單,就是 ip_hash 出現在 upstream 上下文中。
Syntax: ip_hash; Default: — Context: upstream
這里面不得不提到的一個(gè)模塊就是 realip 模塊,哈希算法是根據 remote_addr 這個(gè)變量的值來(lái)進(jìn)行哈希的,這個(gè)變量已經(jīng)出現了好多次了,可見(jiàn)是多么常用的一個(gè)變量。不熟悉的還是到前面Nginx 的 11 個(gè)階段 重新復習一下。
還有另外一個(gè)模塊 upstream_hash 模塊,這個(gè)模塊可以基于任意的關(guān)鍵字實(shí)現 hash 算法的復雜均衡。
基于任意關(guān)鍵字實(shí)現 hash 算法的負載均衡:upstream_hash 模塊
功能:通過(guò)指定關(guān)鍵字作為 hash key,基于 hash 算法映射到特定的上游服務(wù)器中關(guān)鍵字可以含有變量、字符串可以使用 rr 算法的參數
模塊: ngx_http_upstream_hash_module ,通過(guò) --without-http_upstream_ip_hash_module 禁用模塊
指令的話(huà)就是 hash 指令,后面可以跟關(guān)鍵字作為 key。
Syntax: hash key [consistent]; Default: — Context: upstream
實(shí)戰
配置文件如下所示:
log_format varups '$upstream_addr $upstream_connect_time $upstream_header_time $upstream_response_time ' '$upstream_response_length $upstream_bytes_received ' '$upstream_status $upstream_http_server $upstream_cache_status'; upstream iphashups { ip_hash; #hash user_$arg_username; server 127.0.0.1:8011 weight=2 max_conns=2 max_fails=2 fail_timeout=5; server 127.0.0.1:8012 weight=1; } server { set_real_ip_from 127.0.0.1; real_ip_recursive on; real_ip_header X-Forwarded-For; server_name iphash.ziyang.com; listen 80; error_log myerror.log info; access_log logs/upstream_access.log varups; location /{ proxy_pass http://iphashups; proxy_http_version 1.1; proxy_set_header Connection ""; } }
實(shí)際驗證一下,會(huì )發(fā)現不同的 ip 地址實(shí)際上是會(huì )被不同的上游服務(wù)器處理的,如果是同一個(gè) ip 地址,那么只會(huì )被一個(gè)上游服務(wù)器處理。
? nginx curl -H 'X-Forwarded-For: 10.200.20.20' iphash.ziyang.com 8012 server response. ? nginx curl -H 'X-Forwarded-For: 1.200.20.20' iphash.ziyang.com 8011 server response.
基于 IP 或者基于自定義 key 的 hash 算法有一個(gè)嚴重的問(wèn)題,那就是當上游服務(wù)器掛掉的話(huà),Nginx 依然會(huì )向這臺服務(wù)器發(fā)請求,這是因為,如果負載的不同的服務(wù)器上去,可能會(huì )得到異常的響應,同時(shí)還可能導致大量的路由變更。下面的一致性哈??梢越鉀Q這個(gè)問(wèn)題。
一致性哈希算法:hash 模塊
剛才說(shuō)了基于 IP 的哈希算法存在一個(gè)問(wèn)題,那就是當有一個(gè)上游服務(wù)器宕機或者擴容的時(shí)候,會(huì )引發(fā)大量的路由變更,進(jìn)而引發(fā)連鎖反應,導致大量緩存失效等問(wèn)題。那么為什么會(huì )造成這種情況呢?
假設我們基于 key 來(lái)做 hash,現在有 5 臺上游服務(wù)器,如果基于最簡(jiǎn)單的 hash 算法對 key 取模,會(huì )將 key 和 server 一一對應起來(lái)。
當有一臺服務(wù)器宕機的時(shí)候,就需要重新對 key 進(jìn)行 hash,最后會(huì )發(fā)現所有的對應關(guān)系全都失效了,從而會(huì )引發(fā)緩存大范圍失效。
而一致性 hash 算法則可以解決這個(gè)問(wèn)題。
一致性哈希算法的原理是,將一個(gè)環(huán)分成了 2^32 個(gè)區間范圍,四個(gè)節點(diǎn)將這個(gè)環(huán)劃分成為了四個(gè)區間,每個(gè)區間的請求都由對應的節點(diǎn)去處理。來(lái)看看當擴容的時(shí)候會(huì )發(fā)生什么。
假設這時(shí)候發(fā)現 node4 負載過(guò)高,因此決定再添加一個(gè)節點(diǎn)進(jìn)去分擔壓力,那么影響的也只是這個(gè)節點(diǎn)之后的請求,可能會(huì )緩存失效,而其他的三個(gè)節點(diǎn)是不會(huì )有任何影響的。
這就是一致性 hash 算法的原理,一致性 hash 算法使用也很簡(jiǎn)單,只需要將上一節指令中的參數打開(kāi)即可:
Syntax: hash key [consistent]; Default: — Context: upstream
這里只需要指明 consistent 參數即可。
最少連接數算法
再來(lái)看一個(gè)最少連接數算法。這個(gè)算法顧名思義,它會(huì )優(yōu)先選擇連接最少的上游服務(wù)器,是由 upstream_least_conn 模塊提供的。
功能:從所有上游服務(wù)器中,找出當前并發(fā)連接數最少的一個(gè),將請求轉發(fā)到它如果出現多個(gè)最少連接服務(wù)器的連接數都是一樣的,使用 rr 算法
模塊: ngx_http_upstream_least_conn_module ,通過(guò) --without-http_upstream_ip_hash_module 禁用模塊
指令的用法也很簡(jiǎn)單,直接在 upstream 模塊中開(kāi)啟 least_conn 指令即可。
Syntax: least_conn; Default: — Context: upstream
負載均衡策略對所有 worker 進(jìn)程生效:upstream_zone 模塊
上面說(shuō)的所有的負載均衡算法對于 worker 進(jìn)程來(lái)說(shuō)都是獨立的,每個(gè) worker 進(jìn)程之間并不互通,這樣在很多時(shí)候并不是我們期望的。
我們期望的應該是負載均衡算法對所有的 worker 進(jìn)程生效。
功能:分配出共享內存,將其他 upstream 模塊定義的負載均衡策略數據、運行時(shí)每個(gè)上游服務(wù)器的狀態(tài)數據存放在共享內存上,以對所 Nginx worker 進(jìn)程生效
模塊: ngx_http_upstream_zone_module ,通過(guò) --without-http_upstream_ip_hash_module 禁用模塊
一個(gè)指令,指定 zone 的名字以及對應的大?。?/p>
Syntax: zone name [size]; Default: — Context: upstream
除此之外,各個(gè)負載均衡模塊之間是要遵循一定的順序的:
ngx_module_t *ngx_modules[] = { … … &ngx_http_upstream_hash_module, &ngx_http_upstream_ip_hash_module, &ngx_http_upstream_least_conn_module, &ngx_http_upstream_random_module, &ngx_http_upstream_keepalive_module, &ngx_http_upstream_zone_module, … … };
注意,這個(gè)模塊的順序是從上到下執行的,而不是我們前面過(guò)濾模塊的從下到上。
可以看到,zone 模塊在最后,也就是說(shuō),上面各個(gè)算法定義的參數和配置,最終 zone 模塊會(huì )把這些配置放到共享內存里面生效。
這一節介紹了負載均衡的原理以及四種負載均衡算法,也可以說(shuō)是三種,就是輪詢(xún)、哈希、最少連接數算法。每一種算法都有各自的應用場(chǎng)景,rr 算法是最基礎的負載均衡算法,在某些情況下其他算法失效的時(shí)候,會(huì )退化為 rr 算法。
upstream 提供的變量
先來(lái)介紹一組不含緩存的變量。
upstream_addr上游服務(wù)器的 IP 地址,格式為可讀的字符串,例如 127.0.0.1:8012
upstream_connect_time與上游服務(wù)建立連接消耗的時(shí)間,單位為秒,精確到毫秒
upstream_header_time:這個(gè)接收時(shí)間是會(huì )影響到 Nginx 的性能的,因為只有接收了 Header 才能決定下一步如何處理接收上游服務(wù)發(fā)回響應中 HTTP 頭部所消耗的時(shí)間,單位為秒,精確到毫秒
upstream_response_time接收完整的上游服務(wù)響應所消耗的時(shí)間,單位為秒,精確到毫秒
upstream_http_頭部從上游服務(wù)返回的響應頭部的值
upstream_bytes_received從上游服務(wù)接收到的響應長(cháng)度,單位為字節
upstream_response_length從上游服務(wù)返回的響應包體長(cháng)度,單位為字節
upstream_status上游服務(wù)返回的 HTTP 響應狀態(tài)碼。如果未連接上,該變量值為 502
upstream_cookie_名稱(chēng)從上游服務(wù)發(fā)回的響應頭 Set-Cookie 中取出的 cookie 值
upstream_trailer_名稱(chēng)從上游服務(wù)的響應尾部取到的值
來(lái)看一下剛才的實(shí)戰中我們的例子。
在剛才的負載均衡實(shí)戰中有一條日志的配置:
log_format varups '$upstream_addr $upstream_connect_time $upstream_header_time $upstream_response_time ' '$upstream_response_length $upstream_bytes_received ' '$upstream_status $upstream_http_server $upstream_cache_status';
這條配置用到了我們上面提到的很多變量,對應輸出的實(shí)際日志長(cháng)這個(gè)樣子:
127.0.0.1:8012 0.001 0.001 0.001 22 170 200 nginx/1.17.8 -
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站