Nginx 負載均衡upstream_check_module 健康檢查


大家都知道,前端nginx做反向代理,如果后端服務器宕掉的話,nginx是不能把這台real server踢出upstream的,所以還會有請求轉發到后端的這台real server上面去,雖然nginx可以在localtion中啟用proxy_next_upstream來解決返回給用戶的錯誤頁面,但這個還是會把請求轉發給這台服務器的,然后再轉發給別的服務器,這樣就浪費了一次轉發,這次借助與淘寶技術團隊開發的nginx模快nginx_upstream_check_module來檢測后方realserver的健康狀態,如果后端服務器不可用,則所以的請求不轉發到這台服務器。

 轉載於https://blog.csdn.net/qq_34556414/article/details/106636710

nginx_upstream_check_module模塊


nginx_upstream_check_module 是專門提供負載均衡器內節點的健康檢查的外部模塊,由淘寶的姚偉斌大神開發,通過它可以用來檢測后端 realserver 的健康狀態。如果后端 realserver 不可用,則后面的請求就不會轉發到該節點上,並持續檢查幾點的狀態。在淘寶自己的 tengine 上是自帶了該模塊。項目地址:https://github.com/yaoweibin/nginx_upstream_check_module 。  

在淘寶自己的 tengine 上是自帶了該模塊的,大家可以訪問淘寶tengine的官網來獲取該版本的nginx,官方地址:http://tengine.taobao.org/

 

nginx后端健康檢查


nginx自帶健康檢查的缺陷:

  1. Nginx只有當有訪問時后,才發起對后端節點探測。
  2. 如果本次請求中,節點正好出現故障,Nginx依然將請求轉交給故障的節點,然后再轉交給健康的節點處理。所以不會影響到這次請求的正常進行。但是會影響效率,因為多了一次轉發
  3. 自帶模塊無法做到預警
  4. 被動健康檢查

使用第三訪模塊nginx_upstream_check_module:

  1. 區別於nginx自帶的非主動式的心跳檢測,淘寶開發的tengine自帶了一個提供主動式后端服務器心跳檢測模塊
  2. 若健康檢查包類型為http,在開啟健康檢查功能后,nginx會根據設置的間隔向指定的后端服務器端口發送健康檢查包,並根據期望的HTTP回復狀態碼來判斷服務是否健康。
  3. 后端真實節點不可用,則請求不會轉發到故障節點
  4. 故障節點恢復后,請求正常轉發

 

nginx被動檢查


Nginx自帶有健康檢查模塊:ngx_http_upstream_module,可以做到基本的健康檢查,配置如下:

  1.  
    upstream cluster{
  2.  
    server 172.16.0.23:80 max_fails=1 fail_timeout=10s;
  3.  
    server 172.16.0.24:80 max_fails=1 fail_timeout=10s;
  4.  
       # max_fails=1和fail_timeout=10s 表示在單位周期為10s鍾內,中達到1次連接失敗,那么接將把節點標記為不可用,並等待下一個周期(同樣時常為fail_timeout)再一次去請求,判斷是否連接是否成功。
  5.  
       # fail_timeout為10s,max_fails為1次。
  6.  
    }
  7.  
    server {
  8.  
    listen 80;
  9.  
    server_name xxxxxxx.com;
  10.  
    location / {
  11.  
    proxy_pass http://cluster;
  12.  
    }
  13.  
    }

缺點:
Nginx只有當有訪問時后,才發起對后端節點探測。如果本次請求中,節點正好出現故障,Nginx依然將請求轉交給故障的節點,然后再轉交給健康的節點處理。所以不會影響到這次請求的正常進行。但是會影響效率,因為多了一次轉發,而且自帶模塊無法做到預警。

 

nginx主動檢查


主動地健康檢查,nignx定時主動地去ping后端的服務列表,當發現某服務出現異常時,把該服務從健康列表中移除,當發現某服務恢復時,又能夠將該服務加回健康列表中。淘寶有一個開源的實現nginx_upstream_check_module模塊

  1.  
    github地址: https://github.com/yaoweibin/nginx_upstream_check_module
  2.  
    taobao官網: http://tengine.taobao.org/document_cn/http_upstream_check_cn.html

安裝nginx_upstream_check_module 

 安裝擴展模塊,需要編譯安裝的nginx,版本自己選擇(我的是nginx version: nginx/1.16.1)

(1)獲取安裝包

  1.  
    [root@www src]# wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master
  2.  
    Saving to: ?.aster?
  3.  
     
  4.  
    [ <=> ] 175,413 277KB/s in 0.6s
  5.  
     
  6.  
    2020-09-28 10:36:44 (277 KB/s) - ?.aster?.saved [175413]

(2)給nginx打個補丁

(master解壓后的文件為nginx_upstream_check_module-master 里面包含了多個補丁版本,根據自己的nginx版本選擇)

  1.  
    [root@www src] # unzip master
  2.  
    [root@www src] # ls
  3.  
    debug kernels nginx- 1.16.1 nginx_upstream_check_module-master
  4.  
    master nginx- 1.16.1.tar.gz
  5.  
     
  6.  
    #進入nginx-1.16.1源碼目錄,進行打該模塊的補丁(這一步千萬不能遺漏)
  7.  
    [root@www nginx- 1.16.1]# yum install patch-2.7.1-12.el7_7.x86_64 -y
  8.  
    [root@www nginx- 1.16.1]# patch -p1 < /usr/src/nginx_upstream_check_module-master/check_1.16.1+.patch
  9.  
    patching file src/http/modules/ngx_http_upstream_hash_module.c
  10.  
    patching file src/http/modules/ngx_http_upstream_ip_hash_module.c
  11.  
    patching file src/http/modules/ngx_http_upstream_least_conn_module.c
  12.  
    patching file src/http/ngx_http_upstream_round_robin.c
  13.  
    patching file src/http/ngx_http_upstream_round_robin.h

 (3)編譯安裝

  1.  
    [ root@www nginx-1.16.1]# /usr/local/nginx/sbin/nginx -V
  2.  
    nginx version: nginx/1.16.1
  3.  
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
  4.  
    configure arguments: --prefix=/usr/local/nginx
  5.  
    [ root@www nginx-1.16.1]# ./configure --prefix=/usr/local/nginx --add-module=/usr/src/nginx_upstream_check_module-master/
  6.  
    checking for OS
  7.  
    + Linux 3.10.0-693.el7.x86_64 x86_64
  8.  
    checking for C compiler ... found
  9.  
    + using GNU C compiler
  10.  
    + gcc version: 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
  11.  
     
  12.  
    [ root@www nginx-1.16.1]# make && make install
  13.  
     
  14.  
    [ root@www nginx-1.16.1]# make upgrade
  15.  
    /usr/local/nginx/sbin/nginx -t
  16.  
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
  17.  
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
  18.  
    kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`
  19.  
    sleep 1
  20.  
    test -f /usr/local/nginx/logs/nginx.pid.oldbin
  21.  
    kill -QUIT `cat /usr/local/nginx/logs/nginx.pid.oldbin`
  22.  
     
  23.  
    [ root@www nginx-1.16.1]# /usr/local/nginx/sbin/nginx -V
  24.  
    nginx version: nginx/1.16.1
  25.  
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
  26.  
    configure arguments: --prefix=/usr/local/nginx --add-module=/usr/src/nginx_upstream_check_module-master/

 

nginx_upstream_check_module模塊使用


服務治理的一個重要任務是感知服務節點變更,完成服務自動注冊異常節點的自動摘除。這就需要服務治理平台能夠:及時准確的感知service節點的健康狀況。

方案概述

Nginx 提供了三種HTTP服務健康檢查方案供用戶選擇:

  1. TCP層默認檢查方案:

    定時與后端服務建立一條tcp連接,鏈接建立成功則認為服務節點是健康的。

  2. HTTP層默認檢查方案:

    TCP層檢查有一定的局限性:

    1. 很多HTTP服務是帶狀態的,端口處於listen狀態並不能代表服務已經完成預熱;

    2. 不能真實反映服務內部處理邏輯是否產生擁堵。

    3. 這時可以選擇http層健康檢查,會向服務發送一個http請求GET / HTTP/1.0\r\n\r\n,返回狀態是2xx或3xx時認為后端服務正常。

  3. 自定義方案:(nginx_upstream_check_module模塊)

    可根據下文描述自定義檢查方案。

 

配置參數詳解


一個常用的健康檢查配置如下:

  1.  
    check fall=3 interval=3000 rise=2 timeout=2000 type=http;
  2.  
    check_http_expect_alive http_2xx http_3xx ;
  3.  
    check_http_send "GET /checkAlive HTTP/1.0\r\n\r\n" ;

下面針對每個配置參數,進行詳細介紹。

 

check:


check 字段參數如下:

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

check 字段各個參數含義如下:

  • 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提供真實服務的端口一樣。

check_http_expect_alive:


check_http_expect_alive 指定主動健康檢查時HTTP回復的成功狀態:

  1.  
    Syntax: check_http_expect_alive [ http_2xx | http_3xx | http_4xx | http_5xx ]
  2.  
    Default: http_2xx | http_3xx

check_http_send:


check_http_send 配置http健康檢查包發送的請求內容

為了減少傳輸數據量,推薦采用”HEAD”方法。當采用長連接進行健康檢查時,需在該指令中添加keep-alive請求頭,如:”HEAD / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n”。同時,在采用”GET”方法的情況下,請求uri的size不宜過大,確保可以在1個interval內傳輸完成,否則會被健康檢查模塊視為后端服務器或網絡異常。

  1.  
    Syntax: check_http_send http_packet
  2.  
    Default: "GET / HTTP/1.0\r\n\r\n"

 

完整示例


完整示例,如下:

http {
  1.  
    upstream cluster1 {
  2.  
      # simple round-robin
  3.  
      server 192.168.0.1:80;
  4.  
      server 192.168.0.2:80;
  5.  
      check interval=3000 rise=2 fall=5 timeout=1000 type=http;
  6.  
      check_http_send "HEAD / HTTP/1.0\r\n\r\n";
  7.  
      check_http_expect_alive http_2xx http_3xx;
  8.  
      }
  1.  
    upstream cluster2 {
  2.  
      # simple round-robin
  3.  
      server 192.168.0.3:80;
  4.  
      server 192.168.0.4:80;
  5.  
      check interval=3000 rise=2 fall=5 timeout=1000 type=http;
  6.  
      check_keepalive_requests 100;
  7.  
      check_http_send "HEAD / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n";
  8.  
      check_http_expect_alive http_2xx http_3xx;
  9.  
      }
  1.  
    server {
  2.  
      listen 80;
  3.  
      location /1 {
  4.  
      proxy_pass http://cluster1;
  5.  
      }
  1.  
    location /2 {
  2.  
      proxy_pass http://cluster2;
  3.  
      }
  1.  
    location / status {
  2.  
      check_status;
  3.  
      access_log off;
  4.  
      allow SOME.IP.ADD.RESS;
  5.  
      deny all;
  6.  
      }
  7.  
    }
  8.  
    }

 

狀態測試


  1.  
    [ root@www ~]# /usr/local/tomcat/bin/shutdown.sh
  2.  
    Using CATALINA_BASE: /usr/local/tomcat
  3.  
    Using CATALINA_HOME: /usr/local/tomcat
  4.  
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
  5.  
    Using JRE_HOME: /usr/java/jdk1.8.0_131
  6.  
    Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
  7.  
     
  8.  
     
  9.  
    [ root@www ~]# tail -f /usr/local/nginx/logs/error.log
  10.  
    2020/09/28 11:18:38 [notice] 8400#0: using inherited sockets from "6;"
  11.  
    2020/09/28 11:21:05 [notice] 8409#0: signal process started
  12.  
    2020/09/28 11:33:37 [notice] 8419#0: signal process started
  13.  
    2020/09/28 11:33:42 [error] 8420#0: enable check peer: 192.168.179.100:8080
  14.  
    2020/09/28 11:51:23 [error] 8420#0: send() failed (111: Connection refused)
  15.  
    2020/09/28 11:51:26 [error] 8420#0: send() failed (111: Connection refused)
  16.  
    2020/09/28 11:51:29 [error] 8420#0: send() failed (111: Connection refused)
  17.  
    2020/09/28 11:51:32 [error] 8420#0: send() failed (111: Connection refused)
  18.  
    2020/09/28 11:51:35 [error] 8420#0: send() failed (111: Connection refused)
  19.  
    2020/09/28 11:51:35 [error] 8420#0: disable check peer: 192.168.179.100:8080

  1.  
    [root@www ~]# /usr/local/tomcat/bin/startup.sh
  2.  
    Using CATALINA_BASE: /usr/local/tomcat
  3.  
    Using CATALINA_HOME: /usr/local/tomcat
  4.  
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
  5.  
    Using JRE_HOME: /usr/java/jdk1.8.0_131
  6.  
    Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
  7.  
    Tomcat started.
  8.  
     
  9.  
     
  10.  
    2020/09/28 11:52:13 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  11.  
    2020/09/28 11:52:17 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  12.  
    2020/09/28 11:52:22 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  13.  
    2020/09/28 11:52:26 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  14.  
    2020/09/28 11:52:31 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  15.  
    2020/09/28 11:52:35 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  16.  
    2020/09/28 11:52:40 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  17.  
    2020/09/28 11:52:44 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  18.  
    2020/09/28 11:52:49 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  19.  
    2020/09/28 11:52:53 [error] 8420#0: check time out with peer: 192.168.179.100:8080
  20.  
    2020/09/28 11:53:01 [error] 8420#0: enable check peer: 192.168.179.100:8080


免責聲明!

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



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