Nginx文档翻译计划——Http健康检查

160 阅读7分钟

介绍

NGINX 和 F5 NGINX Plus 可以持续对您的upstream server做测试请求,避免已失败的服务器仍然被分发到流量,并优雅地将恢复的服务器重新加入到负载均衡组中。

前提条件

  • 对于被动健康检查,需要 NGINX 开源版或 NGINX Plus
  • 对于主动健康检查和实时活动监控仪表板,需要 NGINX Plus
  • 一组负载均衡的 HTTP upstream server

被动健康检查

对于被动健康检查,NGINX 和 NGINX Plus 会监控实际发生的事务,并尝试恢复失败的连接。如果事务仍然无法恢复,NGINX 开源版和 NGINX Plus 会将服务器标记为不可用,并暂时停止向其发送请求,直到服务器再次被标记为可用。

upstream server被标记为不可用的条件是通过 upstream 块中 server 指令的参数来定义的:

  • fail_timeout:设置在服务器被标记为不可用之前必须发生失败尝试的时间段,同时也是服务器被标记为不可用的时间(默认为 10 秒)。
  • max_fails:设置在 fail_timeout 时间段内必须发生的失败尝试次数,以便将服务器标记为不可用(默认为 1 次)。

在以下示例中,如果 NGINX 在30s内向服务器发送请失败或没有从服务器收到响应 3 次,它会将服务器标记为不可用 30 秒:

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

请注意,如果组中只有一台服务器,则 fail_timeoutmax_fails 参数将被忽略,服务器永远不会被标记为不可用。

服务慢启动(Server Slow Start)

最近恢复的服务器可能会因连接过多而过载,这可能导致服务器再次被标记为不可用。慢启动允许上游服务器在其恢复或变得可用后逐渐将其权重从零恢复到名义值。这可以通过 server 指令的 slow_start 参数来实现:

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

请注意,如果组中只有一台服务器,则 slow_start 参数将被忽略,服务器永远不会被标记为不可用。慢启动功能仅适用于 NGINX Plus。

主动健康检查(Active Health Checks)

NGINX Plus 可以通过定期向每个上游服务器发送专门的健康检查请求并验证正确的响应来检查上游服务器的健康状况。

启用主动健康检查:

  1. In the location that passes requests (proxy_pass) to an upstream group, include the health_check directive: 在要转发请求到upstream group的location include指令health check:
server {
    location / {
        proxy_pass http://backend;
        health_check;
    }
}

此代码片段定义了一个server,它将所有请求(location /)转发到到名为 backend 的upstream group。它还通过 health_check 指令启用了高级健康监控:默认情况下,每 5 秒 NGINX Plus 会向 backend 组中的每个服务器发送一个对根路径(/)的请求。如果发生任何通信错误或超时(服务器返回的状态码不在 200 到 399 范围内),则健康检查失败。服务器将被标记为不健康,NGINX Plus 不会向其发送客户端请求,直到它再次通过健康检查。

您可以为健康检查指定一个端口,例如,用于监控同一主机上的多个不同端口的服务。使用 health_check 指令的 port 参数指定新端口:

server {
    
    location /service1 {
        proxy_pass http://backend;
        health_check;  # 默认检查 80 端口
    }
    
    location / {
        proxy_pass   http://backend;
        health_check port=8080;
    }
}
  1. 在upstream组中,使用 zone 指令定义一个共享内存区域:

    ** Copy

    http {
        upstream backend {
            zone backend 64k;
            server backend1.example.com;
            server backend2.example.com;
            server backend3.example.com;
            server backend4.example.com;
        }
    }
    

该区域在所有工作进程(worker process)中共享,存储upstream group的配置。这使得工作进程可以使用相同的计数器来跟踪组中服务器的响应

可以使用 health_check 指令的参数来覆盖主动健康检查的默认值:

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

在此示例中:

  • interval 参数将健康检查之间的延迟从默认的 5 秒增加到 10 秒。
  • fails 参数要求服务器在被标记为不健康之前必须失败三次健康检查(默认为一次)。
  • passes 参数意味着服务器必须通过两次连续的检查才能再次被标记为健康(默认为一次)。

您可以使用 keepalive_time 参数启用连接缓存——对于 TLS upstream,每次健康检查探针都不会进行完整的 TLS 握手,连接可以在指定的时间内重用:

location / {
    proxy_http_version 1.1;
    proxy_set_header   Connection "";
    proxy_pass         https://backend;
    health_check       interval=1 keepalive_time=60s;
}

指定请求的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

定义自定义条件(Defining Custom Conditions)

您可以设置响应必须满足的自定义条件,以便服务器通过健康检查。这些条件在 match 块中定义,并在 health_check 指令的 match 参数中引用。

http 块中指定 match 块并命名,例如 server_ok

http {
    #...
    match server_ok {
        # tests are here
    }
}

health_check 指令中通过指定 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 范围内,并且其response body不包含字符串 "maintenance mode",则健康检查通过。

match 指令允许 NGINX Plus 检查响应的状态码、header字段和body。使用此指令可以验证状态码是否在指定范围内、响应是否包含某个header字段,或者头字段或body是否匹配正则表达式。match 指令可以包含一个状态条件、一个body条件和多个header条件。响应必须满足 match 块中定义的所有条件,服务器才能通过健康检查。

例如,以下 match 指令匹配状态码为 200、Content-Type 头字段的值为 text/html 且正文中包含文本 "Welcome to nginx!" 的响应:

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

以下示例使用感叹号 (!) 定义响应必须不具备的特性,以便通过健康检查。在这种情况下,如果状态码不是 301、302、303 或 307,并且没有 Refresh header字段,则健康检查通过:

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

强制健康检查 (Mandatory Health Checks)

默认情况下,当新服务器添加到上游组时,NGINX Plus 认为其健康并立即向其发送流量。但对于某些服务器,特别是通过 API 接口或 DNS 解析添加的服务器,最好先进行健康检查再允许它们处理流量。

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

结合慢启动,可以给新服务器更多时间连接数据库并在完全处理流量前“预热”。

强制健康检查可以标记为持久化,以便在重新加载配置时记住之前的健康状态。使用 persistent 参数与 mandatory 参数一起指定:

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 指令的 mandatorypersistent 参数以及 server 指令的 slow_start 参数被指定。通过 API 或 DNS 接口添加到上游组的服务器被标记为不健康,并且在通过健康检查之前不会接收流量;一旦通过健康检查,它们会在 30 秒内逐渐增加接收的流量。如果重新加载 NGINX Plus 配置,并且在重新加载前服务器已被标记为健康,则不会执行强制健康检查,服务器状态将被视为正常。

健康检查也可以为非 HTTP 协议启用,例如 FastCGI、memcached、SCGI、uwsgi 以及 TCP 和 UDP。