一、Nginx心跳检测问题
Nginx自带的针对后端节点健康检查的功能比较简单,主要是通过默认自带的ngx_http_proxy_module 模块和ngx_http_upstream_module模块中的相关指令来完成。实际上,nginx不算是自带健康检查的功能,而是当后端节点出现故障时,会切换到健康节点来提供访问。
如下,是一段我们现在常用的配置
upstream server_meeting_join {
server manager-master:9884 weight=1 max_fails=5 fail_timeout=10s;
server manager-slave-1:9884 weight=1 max_fails=5 fail_timeout=10s;
server manager-slave-2:9884 weight=1 max_fails=5 fail_timeout=10s;
}
权重为1表示请求会依次轮询这三个节点,而max_fails则是设定Nginx与服务器通信的尝试失败的次数,此处设为5,则表示如果失败的次数达到5次,Nginx就认为服务器不可用。但是这样会带来一个问题,如果后端有不健康节点,负载均衡器依然会先把该请求转发给该不健康节点,尝试5次,然后再转发给别的节点,这样就会浪费一次转发,可能会造成响应时间过久。
二、Tengine的健康检查
区别于nginx自带的非主动式的心跳检测,淘宝开发的tengine自带了一个提供主动式后端服务器心跳检测模块nginx_upstream_check_module。具体配置指令详见:http://tengine.taobao.org/document_cn/http_upstream_check_cn.html
若健康检查包类型为http
,在开启健康检查功能后,nginx会根据设置的间隔向指定的后端服务器端口发送健康检查包,并根据期望的HTTP回复状态码来判断服务是否健康。
以server_frontend服务为例,配置如下。该服务能用http的前提在于,nginx通过访问http://ip:host/能够收到状态码回复。
upstream server_frontend {
server manager-master:9887;
server manager-slave-1:9887;
server manager-slave-2:9887;
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_status指令需要在http块中配置,用于显示服务器的健康状态页面,支持的格式有: html
、csv
、 json
。默认类型是html
。该配置在多个配置文件配置一份即可。
location /status {
check_status;
access_log off;
}
访问效果如下:
若后端服务不会返回回复包,那么可以设置健康检查包类型为tcp
。在开启健康检查功能后,nginx会判断tcp连接是否建立成功,以此来判断后端服务是否存活。
例如server_dfs服务,若按上述http的配置,则nginx会认为服务不可用,因为http://ip:host/收不到回复包。
若按tcp的配置(如下),则nginx可以正确地进行辨别。
upstream server_dfs {
server manager-master:9955;
server manager-slave-1:9955;
server manager-slave-2:9955;
check interval=3000 rise=2 fall=5 timeout=1000 type=tcp;
}
如果我们想要设置nginx访问特别的接口,例如server_dfs服务有个心跳检测的接口(/actuator/health),那么可以通过修改check_http_send来实现。配置如下:
upstream server_dfs{
server manager-master:9955;
server manager-slave-1:9955;
server manager-slave-2:9955;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "GET /actuator/health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
三、确保安装第三方模块
目前,我们还是用的nginx,因此若想要安装nginx_upstream_check_module模块,需要以打补丁
的方式进行添加(可参考【Nginx】心跳检测之安装nginx_upstream_check_module模块),因此要确保运维给的nginx包是已经添加该模块的。