Welcome to YARP - 1.認識YARP並搭建反向代理服務
Welcome to YARP - 8.分散式跟蹤
在我們日常系統維護中,系統節點由於各種原因,如過載、資源洩漏、硬體故障等,偶爾會經歷短暫的問題或完全失效。理想情況下,我們希望能夠以主動的方式完全防止這些不幸的事件發生,但設計和構建這樣一個理想系統通常成本過高。然而,還有一種更為經濟的、反應性的方法, 旨在最大限度地減少故障對使用者端請求造成的負面影響。
這種方式可以幫助系統在出現節點問題時更靈活地應對,以提供更可靠的服務。
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
分析目標如何響應代理使用者端請求,評估其新的被動執行狀況狀態,最後呼叫 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
的分散式跟蹤功能。