Http 健康检查

通过发送周期健康检查,监视 upstream 组中 HTTP 服务的健康状态。包括有NGINX Plus 的自定义主动健康检查。

简介

NGINX 和NGINX Plus 能够持续的检测 upstream 中的服务,剔除宕机的服务,还可以优雅的将恢复的的服务添加到负载均衡组群中。

前提

  • 对于被动健康检查,你需要使用开源 NGINX 或者 NGINX Plus
  • 对于主动健康检查和实时活动监视仪表板,你需要使用 NGINX Plus
  • 一个HTTP upstream 负载均衡群组

被动健康检查

对于被动健康检查,NGINX 和NGINX Plus 会监视失败事件的发生,并尝试恢复失败的链接。如果改失败事件不能够不恢复,NGINX 和 NGINX Plus 会将该服务标记为不可达,并暂时停止向改服务转发请求,直到其恢复活跃状态为止。

每个 upstream 服务被标记为不可达的条件被通过参数定义在 server 指令的upstream 块的每一个服务之后。

  • fail_timeout - 设置要将服务器标记为不可用,必须进行多次失败尝试的时间,以及服务器标记为不可用的时间(默认值为10秒)。
  • max_fails - 设置要将服务器标记为不可用,在fail_timeout 周期内最少的失败次数(默认值为1次)。

在下面的例子中,如果 NGINX 在30秒内,无法发送请求或者不能收到服务器的响应3次,它将会标记该服务为不可达30秒:

upstream backend {
    server backend1.example.com;
    server backend2.example.com max_fails=3 fail_time=30s;
}

请注意,如果upstream组内仅有单个服务,fail_timeout 和 max_fails 参数会被忽略,并且该服务永不会被标记为不可达。

服务慢开始

一个刚刚恢复的服务很容易会被链接灌满,这很有可能会导致服务再一次被标记为不可达。慢开始允许在一个upstream 服务恢复或者变成可达状态后将它的权值逐渐的从0恢复到常规状态。这些可以通过在server 指令中使用使用slow_start参数实现:

uptream backend {
    server backend1.example.com slow_start=30s;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

请注意,如果upstream组内仅有单个服务,slow_start 参数会被忽略,并且该服务永不会被标记为不可达。慢开始是NGINX Plus 专有的。

主动健康检查

NGINX Plus 能够通过周期性的向每一个服务发送特定的健康检擦请求并且验证响应的正确性来检查 upstream 服务的健康状态。

启动主动健康检查:

  1. 在向 upstream 服务群组发送请求的 location 块中包含 health_check 指令:
server {
    location / {
        proxy_pass http://backend;
        health_check;
    }
}

该段定义了一个向 backend upstream 群组发送所有请求(location /)的服务。同时通过设置 health_check 默认指令开启了高级健康检查,NGINX Plus 每五秒钟向 backend 群组中的服务发送一次“/”请求。如果任何一次会话错误或者超时(服务响应的的状态码在200到399范围之外),则该次健康检查失败。该服务将会被标记为非健康状态,并且 NGINX Plus 将不会再向其转发客户端请求,直到它下一次通过健康检查。

你可以选择指定另一个端口号用于健康检查,例如再同一个端口检查所有服务的健康状态。可以再 health_check 指令中使用 port 参数:

server {
    location / {
        proxy_pass   http://backend;
        health_check port=8080;
    }
}
  1. 在 upstream 服务群组中使用 zone 指令定义一个共享内存区域:
http {
    upstream backend {
        zone backend 64k;
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com;
        server backend4.example.com;
    }
}

该内存区将会被所有工作进程共享来存储 uptream 群组的配置。这使工作进程能够使用同一组计数器来跟踪来自组中服务器的响应。

默认的主动健康检查可以通过使用 health_check 的参数进行覆盖:

location / {
    proxy_pass http://backend;
    health_check interval=10 fails=3 passes=2;
}

这里,interval参数将健康检查之间的延迟从默认的5秒增加到10秒。fails参数要求服务器在三次运行状况检查中失败,并将其标记为不健康(高于默认值)。最后,passs参数意味着服务器必须通过两个连续的检查才能再次标记为健康,而不是默认的一次。

指定请求的URI

使用 health_check 的 uri 参数来设置进行健康检查请求的URI:

location / {
    proxy_pass http://backend;
    health_check uri=/some/path;
}

指定的URI附加到 upstream 块中为服务器设置的服务器域名或IP地址之后。对于上面声明的示例 backend 群组中的第一台服务器,运行状况检查请求的 URI 为 http://backend1.example.com/some/path。

自定义条件

你可以自定义通过健康检查的服务端响应应该满足的条件。条件定义在 match 块中,match 将会被 health_check 指令的 match 参数引用。

  1. 在 http {}级别指定 match {} 块,并命名,例如,server_ok:
http {
    #...
    match server_ok {
        # tests are here
    }
}
  1. 通过在 health_check 指令的 match 参数中指定 match 块名字的方式引用 match 块:
http {
    #...
    match server_ok {
        status 200-399;
        body !~ "maintenance mode";
    }
    server {
        #...
        location / {
            proxy_pass http://backend;
            health_check match=server_ok;
        }
    }
}

此处,值响应的状态码在200 — 399之间,并且消息体中包含 maintenance mode 时才会通过健康检查。

match 指令允许 NGINX Plus 去检查响应的状态码、消息头部字段和消息体。使用该指令可以检查响应的的状态码是否在指定的范围内,是否包含指定的消息头,消息头或者消息体是否匹配指定的正则表达式。match 指令能够包含一个 status 条件,一个 body 条件和多个 header 条件。一个响应只有满足 match 块中所有的条件,对应的服务才能通过健康检查。

例如,下面的 match 指令匹配状态值为200,头部Content-Type值为 text/html,并且消息体为 “Welcom to nginx!” 的响应:

match welcome {
    status 200;
    header Content-Type = text/html;
    body ~ "Welcome to nginx!";
}

下面的示例使用感叹号(!)来定义响应不能通过健康检查的特征。在本例中,状态码不为301、302、303、307并且没有Refresh头部的响应才能通过健康检查。

match not_redirect {
    status ! 301-303 307;
    header ! Refresh;
}

强制性健康检查

默认情况下,当向 upstream 群组添加新服务时,NGINX Plus 会认为它正常并立即向其发送流量。但对于某些服务,尤其是通过 API 接口或 DNS 解析添加的服务器,最好先执行运行状况检查,然后再允许它们处理流量。

mandatory 参数要求每个新添加的服务器在 NGINX Plus 向其发送流量之前通过所有配置的运行状况检查。

当与慢启动相结合时,它为新服务器提供了更多的时间连接到数据库并在被要求处理其全部流量之前进行“预热”。

强制运行状况检查可以标记为持久,以便在重新加载配置时记住以前的状态。指定持久参数和必需参数:

upstream my_upstream {
    zone my_upstream 64k;
    server backend1.example.com slow_start=30s;
}

server {
    location / {
        proxy_pass   http://my_upstream;
        health_check mandatory persistent;
    }
}

这里指定了 health_check 指令的 mandatory 参数和 persistent 参数以及 server 指令的 slow-start 参数。使用API 或 DNS 接口添加到 upstream 组的服务器被标记为不健康,在通过健康检查之前不会收到流量;在这一点上,他们开始在30秒内接收逐渐增加的流量。如果重新加载NGINX Plus配置,并且在重新加载之前,服务器被标记为健康状态,则不会执行强制健康检查,并且服务器状态被视为已启动。

健康检查也能应用于其他非 HTTP 协议,比如 FastCGI, memcached, SCGI , uwsgi , TCP 和 UDP 。