Nginx心跳檢測

一般咱們會使用Nginx的ngx_http_upstream_module模塊來配置服務器組,示例以下html

 upstream springboot {
 server 10.3.73.223:8080 max_fails=2 fail_timeout=30s;
 server 10.3.73.223:8090 max_fails=2 fail_timeout=30s;
 }
 server {
 listen 80;
 server_name localhost;
 location /test {
 proxy_pass http://springboot;
 }
 }

在30s內(fail_timeout,默認值爲10s),與服務端通信失敗2次(max_fails,默認值爲1,設置爲0則認爲服務端一直可用),則認爲服務器不可用mysql

不可用服務器在30s內與服務端通信成功2次,則認爲服務器恢復nginx

特別須要注意的是,何爲與服務端通信失敗是由upstream的使用方定義的(ngx_http_proxy_module、proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream)git

以proxy_next_upstream爲例:github

與服務端創建鏈接、向服務端發送請求或者解析服務端響應頭時,發生異常或超時將被認爲是通信失敗web

服務端返回的響應爲空或不合法將被認爲是通信失敗spring

若是配置了http_500,http_502,http_503,http_504和http_429,服務端返回這些狀態碼將被認爲是通信失敗sql

服務端返回http_403和http_404永遠不會被認爲通信失敗json

當upstream中的一臺服務器響應失敗時, Nginx會將請求轉發給下一臺服務器,直到全部的服務器都發送過該請求,若是此時依然沒法得到成功的響應,客戶端將收到最後一臺服務器返回的響應結果ubuntu

使用上面的配置進行測試:

package com.sean.test;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* Created by seanzou on 2018/8/20.
*/
@org.springframework.stereotype.Controller
public class Controller {
@RequestMapping("/test")
@ResponseBody
// @ResponseStatus(code= HttpStatus.NOT_FOUND)
@ResponseStatus(code= HttpStatus.INTERNAL_SERVER_ERROR)
public String test(){
System.out.println("test");
// throw new RuntimeException();
return "test";
}
}

即使服務端響應40四、500狀態碼,Nginx依然認爲通信成功,除非停掉當前服務

upstream存在以下一些問題:

1 沒法主動感知服務器狀態

2 配置不靈活,沒法自定義通信失敗判斷條件(僅提供少數定義好的狀態碼可供使用)

1,ngx_http_upstream_hc_module

ngx_http_upstream_hc_module容許週期性的對服務器組中的服務器進行健康檢查,前提條件是服務器組中的服務器必須使用共享內存模式(共享內存用來保存服務器組的配置信息以及運行時狀態,Nginx的woker進程將共享該配置和狀態),示例以下:

  1.  
    upstream dynamic {
  2.  
    # 共享內存
  3.  
    zone upstream_dynamic 64k;
  4.  server backend1.example.com;
  5.  
    server backend2.example.com;
  6.  
    }
  7.  http {
  8.  
    server {
  9.  
    ...
  10.  
    # Nginx每5s(默認值)就會向dynamic中的每個服務器發送「/」請求
  11.  
    # location / {
  12.  
    # proxy_pass http://dynamic;
  13.  
    # health_check;
  14.  
    # }
  15.  # hc能夠經過自定義的校驗規則判斷服務器狀態
  16.  
    location / {
  17.  
    proxy_pass http: //dynamic;
  18.  
    health_check match=welcome;
  19.  
    }
  20.  
    }
  21.  # 若是配置了多個條件,全部條件均知足服務器狀態才被認爲是正常的
  22.  
    # 響應狀態碼爲200,且響應body中包含"Welcome to nginx!"服務器狀態才被認爲是正常的
  23.  
    # Nginx僅檢查響應body中的前256k數據
  24.  
    match welcome {
  25.  
    status 200;
  26.  
    header Content-Type = text/html;
  27.  
    body ~ "Welcome to nginx!";
  28.  
    }
  29.  
    }

功能十分強大,遺憾的是隻有Nginx商業版才包含該模塊

 

2,nginx_upstream_check_module

這個模塊是由淘寶團隊開發的,而且是徹底開源的:nginx_upstream_check_module

淘寶Tengine自帶該模塊,若是咱們沒有使用Tengine,能夠經過打補丁的方式把該模塊加到咱們本身的Nginx中

  1.  
    sean@ubuntu:~$ unzip nginx_upstream_check_module-master.zip
  2.  
    sean@ubuntu:~$ cd nginx-1.14.0/
  3.  
    # 打補丁
  4.  
    sean@ubuntu:~/nginx-1.14.0$ patch -p1 < ../nginx_upstream_check_module-master/check_1.12.1+.patch
  5.  
    # 添加心跳檢測模塊後從新編譯
  6.  
    sean@ubuntu:~/nginx-1.14.0$ sudo ./configure --add-module=../nginx_upstream_check_module-master/
  7.  
    sean@ubuntu:~/nginx-1.14.0$ sudo make
  8.  
    # 備份舊文件
  9.  
    sean@ubuntu:~/nginx-1.14.0$ sudo mv /usr/ local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
  10.  
    # 使用新文件
  11.  
    sean@ubuntu:~/nginx-1.14.0$ sudo cp ./objs/nginx /usr/ local/nginx/sbin/
  12.  
    sean@ubuntu:~/nginx-1.14.0$ sudo /usr/ local/nginx/sbin/nginx -t
  13.  
    nginx: the configuration file /usr/ local/nginx/conf/nginx.conf syntax is ok
  14.  
    nginx: configuration file /usr/ local/nginx/conf/nginx.conf test is successful

修改Nginx配置,官方文檔參考:ngx_http_upstream_check_module document

  1.  
    http {
  2.  
    check_shm_size 1M;
  3.   upstream springboot {
  4.  
    server 10.3.73.223:8080;
  5.  
    server 10.3.73.223:8090;
  6.  
    check interval= 3000 rise=2 fall=5 timeout=1000 type=http;
  7.  
    check_keepalive_requests 1;
  8.  
    check_http_send "GET /test HTTP/1.0\r\n\r\n";
  9.  
    check_http_expect_alive http_2xx;
  10.  
    }
  11.  server {
  12.  
    listen 80;
  13.  
    server_name localhost;
  14.   location /test {
  15.  
    proxy_pass http: //springboot;
  16.  
    }
  17.  location /status {
  18.  
    check_status;
  19.  
    access_log off;
  20.  
    }
  21.  
    }
  22.  
    }

後端服務器健康檢查狀態都存於共享內存中,該指令能夠設置共享內存的大小,若是服務器數量較大,須要注意該設置是否夠用

語法:check_shm_size size

默認值:1M

上下文:http

 

健康檢查規則配置

語法:check interval=milliseconds [fall=count] [rise=count] [timeout=milliseconds] [default_down=true | false]

[type=tcp | http | ssl_hello | mysql | ajp] [port=check_port]

默認值:check interval=30000 fall=5 rise=2 timeout=1000 default_down=true type=tcp

上下文:upstream

interval:向後端發送的健康檢查的間隔時間

fall(fall_count): 連續失敗次數達到fall_count,服務器被認爲是down狀態

rise(rise_count): 連續成功次數達到rise_count,服務器被認爲是up狀態

timeout: 健康檢查請求超時時間

default_down: 設定初始時服務器的狀態,若是是true,服務器默認是down狀態,若是是false,服務器默認是up狀態,默認值是true,也就是一開始服務器被認爲不可用,要等健康檢查請求達到必定成功次數之後纔會被認爲是健康的

type:健康檢查請求協議類型,支持tcp,http,ssl_hello,mysql和ajp

port:健康檢查請求發送端口,能夠與後端服務器服務端口不一樣

 

一個鏈接可發送的請求數,默認值爲1,表示完成1次請求後即關閉鏈接

語法:check_keepalive_requests request_num

默認值:1

上下文:upstream

 

HTTP接口健康檢查發送的請求內容,爲了減小傳輸數據量,推薦採用HEAD方法

語法:check_http_send http_packet

默認值:"GET / HTTP/1.0\r\n\r\n"

上下文:upstream

 

HTTP接口健康檢查成功狀態碼

語法:check_http_expect_alive [http_2xx | http_3xx | http_4xx | http_5xx]

默認值:http_2xx | http_3xx

上下文:upstream

 

後端服務器狀態查詢頁面,提供三種展現方式

語法:check_status [html | csv | json]

默認值:check_status html

上下文:location

 

------------2018-11-29------------

線上環境檢測的worker機使用tomcat做爲容器,check_http_send須要配置Host(僅需配置便可,值是否正確不重要),不然會一直髮送心跳檢測,可是一直斷定檢測失敗,示例以下:

  1.  
    upstream bj{
  2.  
    server 1.2.3.4:80;
  3.  
    server 5.6.7.8:80;
  4.  
    check interval= 5000 rise=2 fall=2 timeout=1000 type=http;
  5.  
    check_http_send "GET /admin/health_check.htm HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n";
  6.  
    check_http_expect_alive http_2xx;
相關文章
相關標籤/搜索