本文章收錄作資料使用,非本人原創,特此說明。html
公司前一段對業務線上的nginx作了整理,重點就是對nginx上負載均衡器的後端節點作健康檢查。目前,nginx對後端節點健康檢查的方式主要有3種,這裏列出:java
- 1、ngx_http_proxy_module 模塊和ngx_http_upstream_module模塊(自帶)
- 官網地址:http://nginx.org/cn/docs/http/ngx_http_proxy_module.html#proxy_next_upstream
- 2、nginx_upstream_check_module模塊
- 官網網址:https://github.com/yaoweibin/nginx_upstream_check_module
- 3、ngx_http_healthcheck_module模塊
- 官網網址:http://wiki.nginx.org/NginxHttpHealthcheckModule
公司業務線上對後端節點的健康檢查是經過nginx_upstream_check_module模塊作的,這裏我將分別介紹這三種實現方式以及之間的差別性。mysql
1、ngx_http_proxy_module 模塊和ngx_http_upstream_module模塊(自帶)linux
嚴格來講,nginx自帶是沒有針對負載均衡後端節點的健康檢查的,可是能夠經過默認自帶的ngx_http_proxy_module 模塊和ngx_http_upstream_module模塊中的相關指令來完成當後端節點出現故障時,自動切換到健康節點來提供訪問。nginx
這裏列出這兩個模塊中相關的指令:git
- 語法: proxy_connect_timeout time;
- 默認值: proxy_connect_timeout 60s;
- 上下文: http, server, location
ngx_http_proxy_module 模塊中的 proxy_connect_timeout 指令、proxy_read_timeout指令和proxy_next_upstream指令.github
設置與後端服務器創建鏈接的超時時間。應該注意這個超時通常不可能大於75秒。
- 語法: proxy_read_timeout time;
- 默認值: proxy_read_timeout 60s;
- 上下文: http, server, location
定義從後端服務器讀取響應的超時。此超時是指相鄰兩次讀操做之間的最長時間間隔,而不是整個響應傳輸完成的最長時間。若是後端服務器在超時時間段內沒有傳輸任何數據,鏈接將被關閉。web
- 語法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off ...;
- 默認值: proxy_next_upstream error timeout;
- 上下文: http, server, location
指定在何種狀況下一個失敗的請求應該被髮送到下一臺後端服務器:sql
- error # 和後端服務器創建鏈接時,或者向後端服務器發送請求時,或者從後端服務器接收響應頭時,出現錯誤
- timeout # 和後端服務器創建鏈接時,或者向後端服務器發送請求時,或者從後端服務器接收響應頭時,出現超時
- invalid_header # 後端服務器返回空響應或者非法響應頭
- http_500 # 後端服務器返回的響應狀態碼爲500
- http_502 # 後端服務器返回的響應狀態碼爲502
- http_503 # 後端服務器返回的響應狀態碼爲503
- http_504 # 後端服務器返回的響應狀態碼爲504
- http_404 # 後端服務器返回的響應狀態碼爲404
- off # 中止將請求發送給下一臺後端服務器
須要理解一點的是,只有在沒有向客戶端發送任何數據之前,將請求轉給下一臺後端服務器纔是可行的。也就是說,若是在傳輸響應到客戶端時出現錯誤或者超時,這類錯誤是不可能恢復的。json
範例以下:
- http {
- proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;
- }
ngx_http_upstream_module模塊中的server指令
- 語法: server address [parameters];
- 默認值: —
- 上下文: upstream
範例以下:
- upstream name {
- server 10.1.1.110:8080 max_fails=1 fail_timeout=10s;
- server 10.1.1.122:8080 max_fails=1 fail_timeout=10s;
- }
下面是每一個指令的介紹:
- max_fails=number # 設定Nginx與服務器通訊的嘗試失敗的次數。在fail_timeout參數定義的時間段內,若是失敗的次數達到此值,Nginx就認爲服務器不可用。在下一個fail_timeout時間段,服務器不會再被嘗試。 失敗的嘗試次數默認是1。設爲0就會中止統計嘗試次數,認爲服務器是一直可用的。 你能夠經過指令proxy_next_upstream、fastcgi_next_upstream和 memcached_next_upstream來配置什麼是失敗的嘗試。 默認配置時,http_404狀態不被認爲是失敗的嘗試。
- fail_timeout=time # 設定服務器被認爲不可用的時間段以及統計失敗嘗試次數的時間段。在這段時間中,服務器失敗次數達到指定的嘗試次數,服務器就被認爲不可用。默認狀況下,該超時時間是10秒。
- 在實際應用當中,若是你後端應用是可以快速重啓的應用,好比nginx的話,自帶的模塊是能夠知足需求的。可是須要注意。若是後端有不健康節點,負載均衡器依然會先把該請求轉發給該不健康節點,而後再轉發給別的節點,這樣就會浪費一次轉發。
- 但是,若是當後端應用重啓時,重啓操做須要好久才能完成的時候就會有可能拖死整個負載均衡器。此時,因爲沒法準確判斷節點健康狀態,致使請求handle住,出現假死狀態,最終整個負載均衡器上的全部節點都沒法正常響應請求。因爲公司的業務程序都是java開發的,所以後端主要是nginx集羣和tomcat集羣。因爲tomcat重啓應部署上面的業務不一樣,有些業務啓動初始化時間過長,就會致使上述現象的發生,所以不是很建議使用該模式。
- 而且ngx_http_upstream_module模塊中的server指令中的max_fails參數設置值,也會和ngx_http_proxy_module 模塊中的的proxy_next_upstream指令設置起衝突。好比若是將max_fails設置爲0,則表明不對後端服務器進行健康檢查,這樣還會使fail_timeout參數失效(即不起做用)。此時,其實咱們能夠經過調節ngx_http_proxy_module 模塊中的 proxy_connect_timeout 指令、proxy_read_timeout指令,經過將他們的值調低來發現不健康節點,進而將請求往健康節點轉移。
- 以上就是nginx自帶的兩個和後端健康檢查相關的模塊。
2、nginx_upstream_check_module模塊
除了自帶的上述模塊,還有一個更專業的模塊,來專門提供負載均衡器內節點的健康檢查的。這個就是淘寶技術團隊開發的 nginx 模塊 nginx_upstream_check_module,經過它能夠用來檢測後端 realserver 的健康狀態。若是後端 realserver 不可用,則因此的請求就不會轉發到該節點上。
在淘寶本身的 tengine 上是自帶了該模塊的,你們能夠訪問淘寶tengine的官網來獲取該版本的nginx,官方地址:http://tengine.taobao.org/。
若是咱們沒有使用淘寶的 tengine 的話,能夠經過補丁的方式來添加該模塊到咱們本身的 nginx 中。咱們業務線上就是採用該方式進行添加的。
下面是部署流程!
一、下載nginx_upstream_check_module模塊
- [root@localhost ~]# cd /usr/local/src
- wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master
- unzip master
- [root@localhost /usr/local/src]# ll -d nginx_upstream_check_module-master
- drwxr-xr-x. 6 root root 4096 Dec 1 02:28 nginx_upstream_check_module-master
二、爲nginx打補丁
- [root@localhost /usr/local/src]# cd nginx-1.6.0 # 進入nginx的源碼目錄
- [root@localhost nginx-1.6.0]# patch -p1 < ../nginx_upstream_check_module-master/check_1.5.12+.patch
- [root@localhost nginx-1.6.0]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx-1.6.0 --with-http_ssl_module --with-openssl=/usr/local/src/openssl-0.9.8q --with-pcre=/usr/local/src/pcre-8.32 --add-module=/usr/local/src/nginx_concat_module/ --add-module=../nginx_upstream_check_module-master/
- make (注意:此處只make,編譯參數須要和以前的同樣)
- [root@localhost nginx-1.6.0]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx-1.6.0.bak
- [root@localhost nginx-1.6.0]# cp ./objs/nginx /usr/local/nginx/sbin/
- [root@localhost nginx-1.6.0]# /usr/local/nginx/sbin/nginx -t # 檢查下是否有問題
- [root@localhost nginx-1.6.0]# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
三、在nginx.conf配置文件裏面的upstream加入健康檢查,以下:
- upstream name {
- server 192.168.0.21:80;
- server 192.168.0.22:80;
- check interval=3000 rise=2 fall=5 timeout=1000 type=http;
-
- }
上面配置的意思是,對name這個負載均衡條目中的全部節點,每一個3秒檢測一次,請求2次正常則標記 realserver狀態爲up,若是檢測 5 次都失敗,則標記 realserver的狀態爲down,超時時間爲1秒。
這裏列出nginx_upstream_check_module模塊所支持的指令意思:
- 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: 指定後端服務器的檢查端口。你能夠指定不一樣於真實服務的後端服務器的端口,好比後端提供的是443端口的應用,你能夠去檢查80端口的狀態來判斷後端健康情況。默認是0,表示跟後端server提供真實服務的端口同樣。該選項出現於Tengine-1.4.0。
- Syntax: check_keepalive_requests request_num
- Default: 1
- Context: upstream
該指令能夠配置一個鏈接發送的請求數,其默認值爲1,表示Tengine完成1次請求後即關閉鏈接。
- 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_status [html|csv|json]
- Default: check_status html
- Context: location
顯示服務器的健康狀態頁面。該指令須要在http塊中配置。
在Tengine-1.4.0之後,你能夠配置顯示頁面的格式。支持的格式有: html、csv、 json。默認類型是html。
你也能夠經過請求的參數來指定格式,假設‘/status’是你狀態頁面的URL, format參數改變頁面的格式,好比:
- /status?format=html
- /status?format=csv
- /status?format=json
同時你也能夠經過status參數來獲取相同服務器狀態的列表,好比:
- 2
- /status?format=html&status=down
- /status?format=csv&status=up
下面是一個狀態也配置的範例:
- http {
- server {
- location /nstatus {
- check_status;
- access_log off;
- #allow IP;
- #deny all;
- }
- }
- }
配置完畢後,重啓nginx。此時經過訪問定義好的路徑,就能夠看到當前 realserver 實時的健康狀態啦。效果以下圖:
realserver 都正常的狀態:
一臺 realserver 故障的狀態:
OK,以上nginx_upstream_check_module模塊的相關信息,更多的信息你們能夠去該模塊的淘寶tengine頁面和github上該項目頁面去查看,下面是訪問地址:
http://tengine.taobao.org/document_cn/http_upstream_check_cn.html
https://github.com/yaoweibin/nginx_upstream_check_module
在生產環境的實施應用中,須要注意的有 2 點:
一、主要定義好type。因爲默認的type是tcp類型,所以假設你服務啓動,不論是否初始化完畢,它的端口都會起來,因此此時前段負載均衡器爲認爲該服務已經可用,實際上是不可用狀態。
二、注意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 /mobileapi HTTP/1.0\r\n HOST www.redhat.sx\r\n\r\n」;
3、ngx_http_healthcheck_module模塊
除了上面兩個模塊,nginx官方在早期的時候還提供了一個 ngx_http_healthcheck_module 模塊用來進行nginx後端節點的健康檢查。nginx_upstream_check_module模塊就是參照該模塊的設計理念進行開發的,所以在使用和效果上都大同小異。可是須要注意的是,ngx_http_healthcheck_module 模塊僅僅支持nginx的1.0.0版本,1.1.0版本之後都不支持了!所以,對於目前常見的生產環境上都不會去用了,這裏僅僅留個記念,給你們介紹下這個模塊!
具體的使用方法,這裏能夠貼出幾篇靠譜的博文地址以及官方地址:
http://wiki.nginx.org/HttpHealthcheckModule
https://github.com/cep21/healthcheck_nginx_upstreams/blob/master/README