目录

Welcome to YARP - 1.认识YARP并搭建反向代理服务

Welcome to YARP - 2.配置功能

Welcome to YARP - 3.负载均衡

Welcome to YARP - 4.限流

Welcome to YARP - 5.身份验证和授权

Welcome to YARP - 6.压缩、缓存

Welcome to YARP - 7.目标健康检查

Welcome to YARP - 8.分布式跟踪

介绍

在我们日常系统维护中,系统节点由于各种原因,如过载、资源泄漏、硬件故障等,偶尔会经历短暂的问题或完全失效。理想情况下,我们希望能够以主动的方式完全防止这些不幸的事件发生,但设计和构建这样一个理想系统通常成本过高。然而,还有一种更为经济的、反应性的方法, 旨在最大限度地减少故障对客户端请求造成的负面影响。

  • 主动目标健康检查(Active Destination Health Checks): 代理系统通过定期主动查询目标节点的状态来判断其健康状况。这样,代理能够主动了解节点的当前状态,并在需要时采取措施,停止将流量发送到不健康的节点。
  • 被动目标健康检查(Passive Destination Health Checks): 代理系统通过观察实际发送到目标节点的请求的响应来判断其健康状况。如果代理检测到目标节点返回了错误或不正常的响应,它可以将该节点标记为不健康,从而停止将流量发送到该节点,直到它恢复正常。

这种方式可以帮助系统在出现节点问题时更灵活地应对,以提供更可靠的服务。

主动健康检查

YARP 可以通过向指定的运行状况终结点发送定期探测请求并分析响应来主动监视目标运行状况。该分析由为集群指定的主动运行状况检查策略执行,并计算新的目标运行状况状态。最后,策略会根据 HTTP 响应代码(2xx 被视为正常)将每个目标标记为正常或不正常,并重新生成群集的正常目标集合。

YARP 提供了一系列配置选项,可以通过配置文件或代码,去控制集群中节点的主动健康检查,同时也提供了一种为每个目标定义专用健康终结点的方式,以满足不同需求的定制化。

配置文件示例

"Clusters": {
"cluster1": {
"HealthCheck": {
"Active": {
"Enabled": "true",
"Interval": "00:00:10",
"Timeout": "00:00:10",
"Policy": "ConsecutiveFailures",
"Path": "/api/health"
}
},
"Metadata": {
"ConsecutiveFailuresHealthPolicy.Threshold": "3"
},
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10000/"
},
"cluster1/destination2": {
"Address": "http://localhost:10010/",
"Health": "http://localhost:10020/"
}
}
}

代码示例

var clusters = new[]
{
new ClusterConfig()
{
ClusterId = "cluster1",
HealthCheck = new HealthCheckConfig
{
Active = new ActiveHealthCheckConfig
{
Enabled = true,
Interval = TimeSpan.FromSeconds(10),
Timeout = TimeSpan.FromSeconds(10),
Policy = HealthCheckConstants.ActivePolicy.ConsecutiveFailures,
Path = "/api/health"
}
},
Metadata = new Dictionary<string, string> { { ConsecutiveFailuresHealthPolicyOptions.ThresholdMetadataName, "5" } },
Destinations =
{
{ "destination1", new DestinationConfig() { Address = "https://localhost:10000" } },
{ "destination2", new DestinationConfig() { Address = "https://localhost:10010", Health = "https://localhost:10010" } }
}
}
};

配置

所有主动健康检查设置中,除了一个例外,其余的都在集群级别的 Cluster/HealthCheck/Active 部分指定。唯一的例外是一个可选的 Destination/Health 元素,用于指定单独的主动健康检查端点。实际的健康探测 URI 的构建方式是 Destination/Address(或设置 Destination/Health) + Cluster/HealthCheck/Active/Path

还可以通过 Yarp.ReverseProxy.Configuration 命名空间中的相应类型在代码中定义主动运行状况检查设置, 这与配置文件中的约定是一致的。

Cluster/HealthCheck/Active 部分和 ActiveHealthCheckConfig

  • Enabled - 指示是否为集群启用主动运行状况检查的标志。默认值 false
  • Interval - 发送运行状况探测请求的时间段。默认值 00:00:15
  • Timeout - 探测请求超时。默认值 00:00:10
  • Policy - 评估目标的活动运行状况状态的策略的名称。强制参数
  • Path - 所有集群目标上的运行状况检查路径。默认 null

Destination 部分和目标配置。

  • Health - 专用的运行状况探测终结点,例如 http://destination:12345/ 默认值 null ,并回退到 Destination/Address (系统将使用目标节点的基础地址作为健康检查的默认地址)。

内置策略

目前有一个内置的主动健康检查策略 - ConsecutiveFailuresHealthPolicy。该策略会计算连续的健康探测失败次数,并在达到给定的阈值后将目标标记为不健康。在第一次成功的响应之后,目标将被标记为健康,并将计数器重置。策略参数在集群的元数据中设置,如下所示:

  • ConsecutiveFailuresHealthPolicy.Threshold - 连续失败的主动健康探测请求的数量,需要达到才能将目标标记为不健康。默认值为 2。

设计 (被动健康检查)

YARP 中的被动健康检查的主要组件和工作流程如下:

  • 主组件:PassiveHealthCheckMiddleware,它位于请求处理管道中,负责分析目标返回的响应。
  • 工作流程:
    1. 对于每个属于启用了被动健康检查的集群的目标返回的响应,PassiveHealthCheckMiddleware 会调用为该集群指定的 IPassiveHealthCheckPolicy
    2. 策略分析给定的响应,评估新目标的被动健康状态,并调用 IDestinationHealthUpdater 来实际更新 DestinationHealthState.Passive 的值。
    3. 更新是在后台异步进行的,不会阻塞请求处理管道。
  • 不健康目标的处理:
    • 当一个目标被标记为不健康时,它将停止接收新的请求,直到在配置的一段时间后重新激活。
    • 激活意味着将目标的 DestinationHealthState.Passive 状态从不健康重置为未知,并重新构建集群的健康目标列表以包括它。
    • 重新激活是由 IDestinationHealthUpdater 在将目标的 DestinationHealthState.Passive 设置为不健康后立即安排重新激活的。
			(对代理请求的响应)
|
PassiveHealthCheckMiddleware (被动健康检查中间件)
|
V
IPassiveHealthCheckPolicy (被动健康检查策略)
|
(评估新的被动健康状态)
|
IDestinationHealthUpdater (目标健康状态更新器) --(异步更新被动状态)--> DestinationState.Health.Passive
|
V
(安排重新激活) --(设置状态为未知)--> DestinationState.Health.Passive

扩展

被动运行状况检查子系统中有一个主要的扩展点,即 IPassiveHealthCheckPolicy

IPassiveHealthCheckPolicy

IPassiveHealthCheckPolicy 分析目标如何响应代理客户端请求,评估其新的被动运行状况状态,最后调用 IDestinationHealthUpdater.SetPassiveAsync 以创建异步任务,实际更新被动运行状况状态并重新生成正常目标集合。

以下是一个简单示例,演示了自定义的 IPassiveHealthCheckPolicy,在代理请求的第一次不成功的响应时将目标标记为不健康。

public class FirstUnsuccessfulResponseHealthPolicy : IPassiveHealthCheckPolicy
{
private static readonly TimeSpan _defaultReactivationPeriod = TimeSpan.FromSeconds(60);
private readonly IDestinationHealthUpdater _healthUpdater; public FirstUnsuccessfulResponseHealthPolicy(IDestinationHealthUpdater healthUpdater)
{
_healthUpdater = healthUpdater;
} public string Name => "FirstUnsuccessfulResponse"; public void RequestProxied(HttpContext context, ClusterState cluster, DestinationState destination)
{
var error = context.Features.Get<IForwarderErrorFeature>();
if (error is not null)
{
var reactivationPeriod = cluster.Model.Config.HealthCheck?.Passive?.ReactivationPeriod ?? _defaultReactivationPeriod;
_healthUpdater.SetPassive(cluster, destination, DestinationHealth.Unhealthy, reactivationPeriod);
}
}
}

可用的目标集合

目标健康状态用于确定哪些目标适合接收代理请求。每个集群都在 ClusterDestinationState 类型的 AvailableDestinations 属性上维护自己的可用目标列表。当任何目标的健康状态发生变化时,该列表将被重新构建。IClusterDestinationsUpdater 控制这个过程,并调用在集群上配置的 IAvailableDestinationsPolicy 来实际选择从所有集群目标中可用的目标。提供了以下内置策略,如果需要,还可以实现自定义策略。

  • HealthyAndUnknown - 检查每个 DestinationState ,如果以下所有语句均为 TRUE,则将其添加到可用目标列表中。如果没有可用的目标,则请求将收到 503 错误。这是默认策略。

    • 主动健康检查在集群上是被禁用的,或者 DestinationHealthState.Active != DestinationHealth.Unhealthy( 这意味着如果目标节点被标记为主动不健康,那么主动健康检查会被禁用 )
    • 被动健康检查在集群上是被禁用的,或者 DestinationHealthState.Passive != DestinationHealth.Unhealthy。( 这意味着如果目标节点被标记为被动不健康,那么被动健康检查会被禁用 )
  • HealthyOrPanic - 首先调用 HealthyAndUnknown 策略以获取可用目标。如果此调用均未返回任何目标,则会将所有集群的目标标记为可用。

注意:无论给定集群上是否启用任何健康检查,都将始终调用配置在集群上的可用目标策略。已禁用健康检查的健康状态设置为未知。

配置

配置文件示例

"Clusters": {
"cluster1": {
"AvailableDestinationsPolicy": "HealthyOrPanic",
"HealthCheck": {
"Passive": {
"Enabled": "true"
}
},
"Destinations": {
"cluster1/destination1": {
"Address": "https://localhost:10000/"
},
"cluster1/destination2": {
"Address": "http://localhost:10010/"
}
}
}

代码示例

var clusters = new[]
{
new ClusterConfig()
{
ClusterId = "cluster1",
HealthCheck = new HealthCheckConfig
{
AvailableDestinationsPolicy = HealthCheckConstants.AvailableDestinations.HealthyOrPanic,
Passive = new PassiveHealthCheckConfig
{
Enabled = true
}
},
Destinations =
{
{ "destination1", new DestinationConfig() { Address = "https://localhost:10000" } },
{ "destination2", new DestinationConfig() { Address = "https://localhost:10010" } }
}
}
};

总结

本章我们介绍了 YARP 的 目标健康检查功能。它有助于提高系统的可用性、稳定性,并帮助及时发现和应对服务故障。 本章暂时没有准备代码示例,有空了再补上吧。

下篇文章我们继续介绍 YARP分布式跟踪功能。

Welcome to YARP - 7.目标健康检查的更多相关文章

  1. 针对后台TCP服务F5健康检查配置

    1.TCP-HALF-OPEN方式 TCP-HALF-OPEN的探测方式,实际是F5每隔一个固定的时间,发送一个SYN包给资源池pool中的一个member,等待服务器返回SYN_ACK,在收到SYN ...

  2. Java应用在docker环境配置容器健康检查

    在<极速体验docker容器健康>一文已体验了docker容器健康检查功能,今天就来给java应用的容器加入健康检查,使应用的状态随时都可以被监控和查看. 实战环境信息 操作系统:macO ...

  3. kubernetes之pod健康检查

    目录 kubernetes之pod健康检查 1.概述和分类 2.LivenessProbe探针(存活性探测) 3.ReadinessProbe探针(就绪型探测) 4.探针的实现方式 4.1.ExecA ...

  4. 《浅谈F5健康检查常用的几种方式》—那些你应该知道的知识(二)

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/sinat_17736151/articl ...

  5. Openshift中Pod的SpringBoot2健康检查

    Openshift中Pod的SpringBoot2应用程序健康检查 1. 准备测试的SpringBoot工程, 需要Java 8 JDK or greater and Maven 3.3.x or g ...

  6. Kubernetes中Pod健康检查

    目录 1.何为健康检查 2.探针分类 2.1.LivenessProbe探针(存活性探测) 2.2.ReadinessProbe探针(就绪型探测) 3.探针实现方法 3.1.Container Exe ...

  7. K8s-Pod健康检查原理与实践

    Pod健康检查介绍 默认情况下,kubelet根据容器运行状态作为健康依据,不能监视容器中应用程序状态,例如程序假死.这将会导致无法提供服务,丢失流量.因此重新健康检查机制确保容器健康幸存.Pod通过 ...

  8. 使用.NET 6开发TodoList应用(28)——实现应用程序健康检查

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 应用健康检查在容器部署的微服务场景下非常常见,相比而言单体非容器部署的应用就不太关心这个特性,为了后续的内容我们在本文中简单介 ...

  9. Kubernetes:健康检查

    Blog:博客园 个人 应用在运行过程中难免会出现错误,如程序异常.软件异常.硬件故障.网络故障等.因此,系统通过一些手段来判断应用是否运行正常,这些手段称之为健康检查(诊断). 前置知识 回顾一下P ...

  10. 【RDA】使用RDA(Remote Diagnostic Agent)工具对数据库进行健康检查

    [RDA]使用RDA(Remote Diagnostic Agent)工具对数据库进行健康检查 分类: Linux RDA英文全称叫做"Oracle Remote Diagnostic Ag ...

随机推荐

  1. KVM 使用 Centos CLoud Image 安装虚拟机

    1 下载镜像 # 资源地址:https://cloud.centos.org/centos/7/images/ wget https://cloud.centos.org/centos/7/image ...

  2. asp.net core之Host

    Host简介 在ASP.NET Core中,Host是一个托管应用程序的宿主环境.它提供了一种统一的方式来启动和运行应用程序,无论是在开发环境中还是在生产环境中.Host负责处理应用程序的生命周期.配 ...

  3. 【青少年CTF】Crypto-easy 题解小集合

    Crypto-easy 1.BASE 拿到附件用cyberchef自动解码得到flag 2.basic-crypto 拿到附件发现是一串01的数字,这时候想到二进制转换 然后base64在线解码 接着 ...

  4. centos7离线安装harbor

    前言 harbor是一个docker私有仓库,基于docker官方的registry,提供GUI.权限控制.项目管理等功能. 安装harbor前,需要先安装docker和docker-compose ...

  5. 震惊!强大的接口自动化测试框架2.0,unittest与pytest无缝穿插对接,可以像postman一样编写代码

    theme: fancy highlight: arta 项目介绍 接口自动化测试项目2.0 软件架构 本框架主要是基于 Python + unittest + ddt + HTMLTestRunne ...

  6. 《SQL与数据库基础》15. 触发器

    目录 触发器 语法 示例-insert型触发器 示例-update型触发器 示例-delete型触发器 本文以 MySQL 为例 触发器 触发器是与表有关的数据库对象,指在 insert/update ...

  7. 为何每个开发者都在谈论Go?

    本文深入探讨了Go语言的多个关键方面,从其简洁的语法.强大的并发支持到出色的性能优势,进一步解析了Go在云原生领域的显著应用和广泛的跨平台支持.文章结构严谨,逐一分析了Go语言在现代软件开发中所占据的 ...

  8. python flask 提供web的get/post开发

    转载请注明出处: 使用python flask框架编写web api中的get与post接口,代码编写与调试示例如下: from flask import Flask, request, jsonif ...

  9. 探索 Java 线程的创建

    by emanjusaka from ​ https://www.emanjusaka.top/archives/7 彼岸花开可奈何 本文欢迎分享与聚合,全文转载请留下原文地址. 前言 在并发编程中我 ...

  10. C#应用程序的多语言方案 - 开源研究系列文章

    今天讲讲笔者自创的C#应用程序多语言的方案. 这个多语言方案,主要是对应用的窗体及其控件进行检索,然后根据控件的名称进行在语言字典里进行检索获取到对应的语言文本进行赋值显示的.笔者对网上的多语言方案进 ...