Welcome to YARP - 7.目标健康检查
目录
Welcome to YARP - 1.认识YARP并搭建反向代理服务
- 2.1 - 配置文件(Configuration Files)
- 2.2 - 配置提供者(Configuration Providers)
- 2.3 - 配置过滤器(Configuration Filters)
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
,它位于请求处理管道中,负责分析目标返回的响应。 - 工作流程:
- 对于每个属于启用了被动健康检查的集群的目标返回的响应,
PassiveHealthCheckMiddleware
会调用为该集群指定的IPassiveHealthCheckPolicy
。 - 策略分析给定的响应,评估新目标的被动健康状态,并调用
IDestinationHealthUpdater
来实际更新DestinationHealthState.Passive
的值。 - 更新是在后台异步进行的,不会阻塞请求处理管道。
- 对于每个属于启用了被动健康检查的集群的目标返回的响应,
- 不健康目标的处理:
- 当一个目标被标记为不健康时,它将停止接收新的请求,直到在配置的一段时间后重新激活。
- 激活意味着将目标的
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.目标健康检查的更多相关文章
- 针对后台TCP服务F5健康检查配置
1.TCP-HALF-OPEN方式 TCP-HALF-OPEN的探测方式,实际是F5每隔一个固定的时间,发送一个SYN包给资源池pool中的一个member,等待服务器返回SYN_ACK,在收到SYN ...
- Java应用在docker环境配置容器健康检查
在<极速体验docker容器健康>一文已体验了docker容器健康检查功能,今天就来给java应用的容器加入健康检查,使应用的状态随时都可以被监控和查看. 实战环境信息 操作系统:macO ...
- kubernetes之pod健康检查
目录 kubernetes之pod健康检查 1.概述和分类 2.LivenessProbe探针(存活性探测) 3.ReadinessProbe探针(就绪型探测) 4.探针的实现方式 4.1.ExecA ...
- 《浅谈F5健康检查常用的几种方式》—那些你应该知道的知识(二)
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/sinat_17736151/articl ...
- Openshift中Pod的SpringBoot2健康检查
Openshift中Pod的SpringBoot2应用程序健康检查 1. 准备测试的SpringBoot工程, 需要Java 8 JDK or greater and Maven 3.3.x or g ...
- Kubernetes中Pod健康检查
目录 1.何为健康检查 2.探针分类 2.1.LivenessProbe探针(存活性探测) 2.2.ReadinessProbe探针(就绪型探测) 3.探针实现方法 3.1.Container Exe ...
- K8s-Pod健康检查原理与实践
Pod健康检查介绍 默认情况下,kubelet根据容器运行状态作为健康依据,不能监视容器中应用程序状态,例如程序假死.这将会导致无法提供服务,丢失流量.因此重新健康检查机制确保容器健康幸存.Pod通过 ...
- 使用.NET 6开发TodoList应用(28)——实现应用程序健康检查
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 应用健康检查在容器部署的微服务场景下非常常见,相比而言单体非容器部署的应用就不太关心这个特性,为了后续的内容我们在本文中简单介 ...
- Kubernetes:健康检查
Blog:博客园 个人 应用在运行过程中难免会出现错误,如程序异常.软件异常.硬件故障.网络故障等.因此,系统通过一些手段来判断应用是否运行正常,这些手段称之为健康检查(诊断). 前置知识 回顾一下P ...
- 【RDA】使用RDA(Remote Diagnostic Agent)工具对数据库进行健康检查
[RDA]使用RDA(Remote Diagnostic Agent)工具对数据库进行健康检查 分类: Linux RDA英文全称叫做"Oracle Remote Diagnostic Ag ...
随机推荐
- 记一次使用pagehelper的坑(返回的total和size每页条数一致的问题)
问题描述 众所周知,pagehelper使用时应该在dao查询语句的前一句加上PageHelper.startPage,所以标题的问题由此引出-- 原因 PageHelper.startPage使用后 ...
- OpenLayers文档
https://openlayers.org/en/latest/apidoc/module-ol_interaction_DragZoom-DragZoom.html#changed
- 浏览器端模块化方式es module详解
在es module出现之前还有社区推出amd和cmd的规范,这两者还有其特定的编写方式,使用起来不算很方便.es module被官方推出来就成为了浏览器端实现模块化的一个很好的方案. 想要在浏览 ...
- php批量同步数据
php批量同步流程 首先分页获取数据 创建临时表 批量添加数据 备份原表 删除原表 修改临时表表名改为原表 代码 1 <?php 2 3 class Stock{ 4 5 private $da ...
- Python 潮流周刊#16:优雅重要么?如何写出 Pythonic 的代码?
你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中两则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...
- Geotools实现shape文件的写入
众所周知Geotools作为开源的Java GIS三方库,已经成为GIS服务器端的主流开源库,其功能非常强大,涉及到GIS业务的方方面面,其中就包括GIS数据的读写,今天小编就借助Geotools来实 ...
- 9、Spring之代理模式
9.1.环境搭建 9.1.1.创建module 9.1.2.选择maven 9.1.3.设置module名称和路径 9.1.4.module初始状态 9.1.5.配置打包方式和依赖 <?xml ...
- Win10安装Oracle-21C
1.前期工作 下载安装包:OracleXE213_Win64.zip 解压安装包 2.开始安装 注意:以管理员身份运行 ++++++++++++++++++++++分割线+++++++++++++++ ...
- ImGui界面优化:使用图标字体、隐藏主窗口标题栏
目录 使用图标字体 扩展:内存加载字体 隐藏主窗口标题栏 增加程序退出 改进HideTabBar 窗口最大化 总结 本文主要介绍ImGui应用中的一些界面优化方法,如果是第一次使用ImGui推荐从上一 ...
- AI绘画Stable Diffusion实战操作: 62个咒语调教-时尚杂志封面
今天来给大家分享,如何用sd简单的咒语输出好看的图片的教程,今天做的是时尚杂志专题,话不多说直入主题. 还不会StableDiffusion的基本操作,推荐看看这篇保姆级教程: AI绘画:Stable ...