nginx原生的健康检测主要涉及两个模块:ngx_http_proxy_module和ngx_http_upstream_module


一、ngx_http_upstream_module模块

upstream backend {

    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;

}


1.max_fails

设定Nginx与服务器通信的尝试失败的次数。在fail_timeout参数定义的时间段内,如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout时间段,服务器不会再被尝试。 失败的尝试次数默认是1。设为0就会停止统计尝试次数,认为服务器是一直可用的。 你可以通过指令proxy_next_upstream、fastcgi_next_upstream和 memcached_next_upstream来配置什么是失败的尝试。 默认配置时,http_404状态不被认为是失败的尝试。


2.fail_timeout

设定服务器被认为不可用的时间段以及统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数,服务器就被认为不可用。默认情况下,该超时时间是10秒。


二、ngx_http_proxy_module模块

1.proxy_connect_timeout

与后端服务器建立连接的超时时间


2.proxy_read_timeout

定义从后端服务器读取响应的超时。此超时是指相邻两次读操作之间的最长时间间隔,而不是整个响应传输完成的最长时间。如果后端服务器在超时时间段内没有传输任何数据,连接将被关闭


3.proxy_next_upstream

指定在何种情况下一个失败的请求应该被发送到下一台后端服务器


需要理解一点的是,只有在没有向客户端发送任何数据以前,将请求转给下一台后端服务器才是可行的。也就是说,如果在传输响应到客户端时出现错误或者超时,这类错误是不可能恢复的。



三、原生nginx的健康检测存在的问题


1.节点异常:如果后端节点异常,nginx依然会先把该请求转发给该异常节点,然后再转发给别的节点,这样就会浪费一次转发。当尝试max_fails次失败后才会将其设置为异常节点。

2.无法精确判断异常节点是否恢复:判断为异常的节点,在fail_timeout时间后,nginx直接使用线上流量去请求异常节点,而不是先探测是否恢复,在导入线上流量



四、使用第三方健康检测模块nginx_upstream_check_module

使用第三方检测模块可以很好的解决上述问题。

在编译了nginx_upstream_check_module模块后,可以在upstream中定义。


check interval=milliseconds [fall=count] [rise=count] [timeout=milliseconds] [default_down=true|false] [type=tcp|http|ssl_hello|mysql|ajp]


- 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提供真实服务的端口一样。