nginx 判斷節點失效狀態:
Nginx 默認判斷失敗節點狀態以connect refuse和time out狀態為准,不以HTTP錯誤狀態進行判斷失敗,因為HTTP只要能返回狀態說明該節點還可以正常連接,所以nginx判斷其還是存活狀態;
除非添加了proxy_next_upstream指令設置對404、502、503、504、500和time out等錯誤進行轉到備機處理,
在next_upstream過程中,會對fails進行累加,如果備用機處理還是錯誤則直接返回錯誤信息(但404不進行記錄到錯誤數,如果不配置錯誤狀態也不對其進行錯誤狀態記錄)
綜述,nginx記錄錯誤數量只記錄timeout 、connect refuse、502、500、503、504這6種狀態,timeout和connect refuse是永遠被記錄錯誤狀態,
而502、500、503、504只有在配置proxy_next_upstream后nginx才會記錄這4種HTTP錯誤到fails中,當fails大於等於max_fails時,則該節點失效
nginx 處理節點失效和恢復的觸發條件:
nginx可以通過設置max_fails(最大嘗試失敗次數)和fail_timeout(失效時間,在到達最大嘗試失敗次數后,在fail_timeout的時間范圍內節點被置為失效,除非所有節點都失效,否則該時間內,節點不進行恢復)對節點失敗的嘗試次數和失效時間進行設置,
當超過最大嘗試次數或失效時間未超過配置失效時間,則nginx會對節點狀會置為失效狀態,nginx不對該后端進行連接,直到超過失效時間或者所有節點都失效后,該節點重新置為有效,重新探測;
所有節點失效后nginx將重新恢復所有節點進行探測:
如果探測所有節點均失效,備機也為失效時,那么nginx會對所有節點恢復為有效,重新嘗試探測有效節點,如果探測到有效節點則返回正確節點內容,如果還是全部錯誤,那么繼續探測下去,
當沒有正確信息時,節點失效時默認返回狀態為502,但是下次訪問節點時會繼續探測正確節點,直到找到正確的為止。
一、ngx_http_proxy_module模塊和ngx_http_upstream_module模塊(自帶)
Nginx 在 upstream 模塊中的默認檢測機制:通過用戶的真實請求去檢查被代理服務器的可用性,這是一種被動的檢測機制,通過 ngx_http_upstream_module 模塊中 server 指令的指令值參數 max_fails 及 fail_timeout 實現對被代理服務器的檢測和熔斷。
upstream test1 {
#10s內出現3次錯誤,該服務器將被熔斷10s server 192.168.134.154:80 max_fails=3 fails_timeout=10s; server 192.168.134.153:80 max_fails=3 fails_timeout=10s; server 192.168.134.152:80 max_fails=3 fails_timeout=10s; } server { proxy_connect_timeout 5s; #與被代理服務器建立連接的超時時間 proxy_read_timeout 10s; #獲取被代理服務器的響應最大超時時間,當與被代理服務器通信出現指令值指定的情況時,認為被代理出錯,並將請求轉發給上游服務器組中的下一個可用服務器 proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header; proxy_next_upstream_teies 3; #轉發請求最大次數 proxy_next_upstream_timeout 10s; #總嘗試超時時間
max_fails: 10s 內 Nginx 分配給當前服務器的請求失敗次數累加值,每 10s 會重置為 0
fail_timeout:既是失敗計數的最大時間,又是服務器被置為失敗狀態的熔斷時間,超過這個時間將再次被分配
指令 proxy_connect_timeout 或 proxy_read_timeout 為超時狀態時,都會觸發 proxy_next_upstream 的 timeout 條件
proxy_next_upstream:Nginx 提高請求成功率的機制,當被代理服務器返回錯誤並符合 proxy_next_upstream 指令值設置的條件時,將嘗試轉發給下一個可用的被代理服務器
Nginx 被動檢測機制的優點是不需要增加額外進程進行健康檢測,但用該方法檢測是不准確的。如當響應超時時,有可能是被代理服務器故障,也可能是業務響應慢引起的。
如果是被代理服務器故障,那么 Nginx 仍會在一定時間內將客戶端的請求轉發給該服務器,用以判斷其是否恢復。
二、nginx_upstream_check_module模塊(淘寶技術團隊開發)
檢測后方realserver的健康狀態,如果后端服務器不可用,則會將其踢出upstream,所有的請求不轉發到這台服務器;當恢復正常時,將其加入upstream
upstream test1 { server 192.168.134.154:80; server 192.168.134.153:80; server 192.168.134.152:80;
#每隔5秒檢測一次,請求2次正常則標記 realserver狀態為up,如果檢測5次都失敗,則標記 realserver的狀態為down,超時時間為1秒,使用http協議。 check interval=5000 rise=2 fall=5 timeout=1000 type=http; check_http_send"HEAD / HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; }
Syntax: check interval=milliseconds [fall=count] [rise=count] [timeout=milliseconds] [default_down=true|false] [type=tcp|http|ssl_hello|mysql|ajp] [port=check_port] Default: 如果沒有配置參數,默認值是:interval=30000 fall=5 rise=2 timeout=1000 default_down=true type=tcp Context: upstream
參數說明:
參數 | 描述 |
interval | 向后端發送的健康檢查包的間隔 |
fall(fall_count) | 如果連續失敗次數達到fall_count,服務器就被認為是down |
rise(rise_count) | 如果連續成功次數達到rise_count,服務器就被認為是up |
timeout | 后端健康請求的超時時間,單位毫秒 |
default_down | 設定初始時服務器的狀態,如果是true,就說明默認是down的,如果是false,就是up的。默認值是true,也就是一開始服務器認為是不可用,要等健康檢查包達到一定成功次數以后才會被認為是健康的 |
type | 健康檢查包的類型,現在支持以下多種類型: |
tcp:簡單的tcp連接,如果連接成功,就說明后端正常 | |
ssl_hello:發送一個初始的SSL hello包並接受服務器的SSL hello包 | |
http:發送HTTP請求,通過后端的回復包的狀態來判斷后端是否存活 | |
mysql: 向mysql服務器連接,通過接收服務器的greeting包來判斷后端是否存活 | |
ajp:向后端發送AJP協議的Cping包,通過接收Cpong包來判斷后端是否存活 | |
port: 指定后端服務器的檢查端口。可以指定不同於真實服務的后端服務器的端口,默認是0,表示跟后端server提供真實服務的端口一樣 |
Syntax: check_http_send http_packet Default: "GET / HTTP/1.0\r\n\r\n" Context: upstream #該指令可以配置http健康檢查包發送的請求內容。為了減少傳輸數據量,推薦采用"HEAD"方法。
#當采用長連接進行健康檢查時,需在該指令中添加keep-alive請求頭,如:"HEAD / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n"。
#同時,在采用"GET"方法的情況下,請求uri的size不宜過大,確保可以在1個interval內傳輸完成,否則會被健康檢查模塊視為后端服務器或網絡異常。
Syntax: check_http_expect_alive [ http_2xx | http_3xx | http_4xx | http_5xx ] Default: http_2xx | http_3xx Context: upstream #該指令指定HTTP回復的成功狀態,默認認為2XX和3XX的狀態是健康的。
Syntax: check_shm_size size
Default: 1M
Context: http
#所有的后端服務器健康檢查狀態都存於共享內存中,該指令可以設置共享內存的大小。默認是1M,如果有1千台以上的服務器並在配置的時候出現了錯誤,就可能需要擴大該內存的大小。
Syntax: check_keepalive_requests request_num Default: 1 Context: upstream #該指令可以配置一個連接發送的請求數,其默認值為1,表示Tengine完成1次請求后即關閉連接。
Syntax: check_status [html|csv|json]
Default: check_status html
Context: location
#顯示服務器的健康狀態頁面。該指令需要在http塊中配置。在Tengine-1.4.0以后,可以配置顯示頁面的格式。支持的格式有: html、csv、 json。默認類型是html。
配置時需注意:
1)type:由於默認的type是tcp類型,因此假設服務啟動,不管是否初始化完畢,它的端口都會起來,所以此時前段負載均衡器為認為該服務已經可用,其實是不可用狀態。
2)check_http_send:默認值是"GET / HTTP/1.0\r\n\r\n" 假設應用是通過http://ip/name訪問的,那么這里check_http_send值就需要更改為 "GET /name HTTP/1.0\r\n\r\n"才可以。
針對采用長連接進行檢查的, 增加 keep-alive請求 頭,即"HEAD /name HTTP/1.1\r\nConnection: keep-alive\r\n\r\n"。
如果后端的tomcat是基於域名的多虛擬機,此時需要通過 check_http_send定義host,不然每次訪問都是失敗,范例:check_http_send "GET /test HTTP/1.0\r\n HOST wwwnginx.com\r\n\r\n";
三、ngx_http_healthcheck_module
官方在早期的時候提供的用來進行nginx后端節點的健康檢查,nginx_upstream_check_module模塊就是參照該模塊的設計理念進行開發的,因此在使用和效果上都大同小異。
ngx_http_healthcheck_module模塊僅僅支持nginx的1.0.0版本,1.1.0版本以后都不支持了,這里不做闡述。