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