目錄 Welcome to YARP - 1.認識YARP並搭建反向代理服務 Welcome to YARP - 2.配置功能 2.1 - 配置文件(Configuration Files) 2.2 - 配置提供者(Configuration Providers) 2.3 - 配置過濾器(Confi ...
目錄
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
的分散式跟蹤功能。