nginx 添加第三方nginx_upstream_check_module 模塊實現健康狀態檢測


目的

檢測后端relaserver 真實狀態,使用前端負載均衡器nginx做到后端服務出錯時,自動將出錯的節點路踢掉,使得正常請求不發往出錯的后端節點,當出錯的后端節點恢復后,又能將節點自動加入集群中。nginx自身雖然帶有簡單的健康檢測,但並不有效。

些處使用第三方插件:
nginx_upstream_check_module Health check HTTP servers inside an upstream
https://github.com/yaoweibin/nginx_upstream_check_modue

安裝插件

下載

$ wget  https://github.com/yaoweibin/nginx_upstream_check_module/archive/v0.3.0.tar.gz
$ tar xf v0.3.0.tar.gz 
$ cd nginx_upstream_check_module-0.3.0
$ ls -l
total 244
-rw-rw-r-- 1 root root      0 Oct  2  2014 CHANGES
-rw-rw-r-- 1 root root   5483 Oct  2  2014 check_1.2.1.patch      #相應版本的補丁
-rw-rw-r-- 1 root root   7130 Oct  2  2014 check_1.2.2+.patch
-rw-rw-r-- 1 root root   7094 Oct  2  2014 check_1.2.6+.patch
-rw-rw-r-- 1 root root   6791 Oct  2  2014 check_1.5.12+.patch
-rw-rw-r-- 1 root root   6701 Oct  2  2014 check_1.7.2+.patch
...

安裝

$ nginx -V   #此處省略了很多模塊,只是為了看清而已
...
configure arguments: --prefix=/usr/local/nginx  --add-module=../lua-nginx-module-0.10.8

$ cd /usr/local/src/nginx-1.8.1
#給nginx打補丁(根據nginx版本號選擇補丁包),打補丁這步操作不可少,否則會出出"[error] 29841#0: *23 http upstream check module can not find any check server, make sure you've added the check servers," 錯誤
$ patch -p1 < /usr/local/src/nginx_upstream_check_module-0.3.0/check_1.7.2+.patch   
patching file src/http/modules/ngx_http_upstream_ip_hash_module.c
patching file src/http/modules/ngx_http_upstream_least_conn_module.c
patching file src/http/ngx_http_upstream_round_robin.c
Hunk #1 succeeded at 9 with fuzz 2.
Hunk #2 succeeded at 95 (offset 4 lines).
Hunk #3 succeeded at 159 (offset 4 lines).
Hunk #4 succeeded at 227 (offset 4 lines).
Hunk #5 succeeded at 339 (offset 4 lines).
Hunk #6 succeeded at 381 (offset 4 lines).
Hunk #7 succeeded at 443 (offset 4 lines).
Hunk #8 succeeded at 541 (offset -1 lines).
patching file src/http/ngx_http_upstream_round_robin.h

$ ./configure --prefix=/usr/local/nginx  --add-module=../lua-nginx-module-0.10.8 --add-module=../nginx_upstream_check_module-0.3.0 
....
$ make
#make (注意:此處只make,編譯參數需要和之前的一樣,不要執行make install,否則就會覆蓋正在使用的nginx)

$ mv /usr/loca/nginx/sbin/nginx{,_bak}
$ mv objs/nginx /usr/local/nginx/sbin/
$ nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
 
$ kill -USER2 `cat /usr/local/nginx/logs/nginx.pid` #熱升級nginx,之前的文章有講過,如果當前nginx不是用絕對路徑下的nginx命令啟動的話,熱升級無效。只能`nginx -s stop`&& /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf`

配置說明

$ less nginx.conf  #配置段
    http {
        upstream cluster {
            # simple round-robin
            server 192.168.0.1:80;
            server 192.168.0.2:80;

            check interval=5000 rise=1 fall=3 timeout=4000;
            #check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello;
            #check interval=3000 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;
        }
...
  check
    syntax: *check interval=milliseconds [fall=count] [rise=count]
    [timeout=milliseconds] [default_down=true|false]
    [type=tcp|http|ssl_hello|mysql|ajp|fastcgi]*

   默認配置:interval=3000 fall=5 rise=2 timeout=1000 default_down=true type=tcp*
...
  • interval: 檢測間隔3秒
  • fall: 連續檢測失敗次數5次時,認定relaserver is down
  • rise: 連續檢測成功2次時,認定relaserver is up
  • timeout: 超時1秒
  • default_down: 初始狀態為down,只有檢測通過后才為up
  • type: 檢測類型方式 tcp
    1. tcp :tcp 套接字,不建議使用,后端業務未100%啟動完成,前端已經放開訪問的情況
    2. ssl_hello: 發送hello報文並接收relaserver 返回的hello報文
    3. http: 自定義發送一個請求,判斷上游relaserver 接收並處理
    4. mysql: 連接到mysql服務器,判斷上游relaserver是否還存在
    5. ajp: 發送AJP Cping數據包,接收並解析AJP Cpong響應以診斷上游relaserver是否還存活(AJP tomcat內置的一種協議)
    6. fastcgi: php程序是否存活
check_http_send "HEAD / HTTP/1.0\r\n\r\n";
check_http_expect_alive  http_2xx http_3xx ;

如果將檢查類型設置為http,則可以通過請求指定資源來判斷后端relaserver是否error。同時判斷后端返回的狀態碼是否為2xx和3xx,是表示檢查通過,否則表示失敗。

示例
upstream cluster {
  server 192.168.20.12:80;
  server 192.168.20.3:80;     #未啟動web服務,默認為down

  check interval=3000 rise=2 fall=3 timeout=1000 type=http;
  check_http_send "GET /index.html HTTP/1.0\r\n\r\n";   #獲取后端資源,資源變動后,經歷三次檢查周期后立即將狀態改為down
  check_http_expect_alive  http_2xx http_3xx ; #check_http_send 返回狀態碼,2xx和3xx為默認值。
}

server {
        listen 80;
        location / {
            proxy_pass http://cluster;
        }
        location = /status {
            check_status;
            #allow xxx;
            #deny all;
       }
}

在使用GET方法時,請求的uri不宜過大。

Syntax: check_shm_size size
Default: 1M
Context: http

所有的后端服務器健康檢查狀態都存於共享內存中,該指令可以設置共享內存的大小。默認是1M,在配置的時候出現了錯誤,就可能需要擴大該內存的大小(后端服務較多的情況)。

Syntax: check_status [html|csv|json]
Default: check_status html
Context: location

后端服務器狀態展示方式,默認html適合瀏覽器訪問,如果需要使用第三方監控可以使用json方式。

$ vim xxx.conf
...
        location = /status {
            check_status json;
            ...
        }

$ curl http://192.168.20.10/status?format=json
{"servers": {
  "total": 2,
  "generation": 2,
  "server": [
    {"index": 0, "upstream": "cluster", "name": "192.168.20.12:80", "status": "up", "rise": 202, "fall": 0, "type": "http", "port": 0},
    {"index": 1, "upstream": "cluster", "name": "192.168.20.3:80", "status": "down", "rise": 0, "fall": 228, "type": "http", "port": 0}
  ]
}}

注意事項

  1. 如果后端是基於域名訪問,可使用check_http_send "GET /xxx HTTP/1.0\r\n HOST www.xxx.com\r\n\r\n";方式在請求時添加請求頭信息

總結

此模塊已經很好的解決了健康狀態檢測功能,並提供自動恢復功能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM