首頁 資訊 ASP.NET Core 中的健康狀態(tài)檢查

ASP.NET Core 中的健康狀態(tài)檢查

來源:泰然健康網(wǎng) 時間:2024年12月13日 15:59
跳到主要內(nèi)容

已不再支援此瀏覽器。

請升級至 Microsoft Edge,以利用最新功能、安全性更新和技術(shù)支援。

ASP.NET Core 中的健康狀態(tài)檢查

發(fā)行項(xiàng)2024/11/06

本文內(nèi)容

基本健康狀態(tài)探查建立健康狀態(tài)檢查登錄健康狀態(tài)檢查服務(wù)使用健康情況檢查路由傳送健康狀態(tài)檢查選項(xiàng)資料庫探查Entity Framework Core DbContext 探查個別的整備度與活躍度探查發(fā)佈健康狀態(tài)檢查程式庫健康狀態(tài)檢查發(fā)行者相依性插入和健康情況檢查UseHealthChecks 與MapHealthChecks其他資源

作者:Glenn Condron 和 Juergen Gutsch

注意

這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。

重要

這些發(fā)行前產(chǎn)品的相關(guān)資訊在產(chǎn)品正式發(fā)行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔(dān)保。

如需目前的版本,請參閱 本文的 .NET 9 版本。

ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應(yīng)用程式基礎(chǔ)結(jié)構(gòu)元件的健康情況。

應(yīng)用程式會將健康狀態(tài)檢查公開為 HTTP 端點(diǎn)。 您可以針對各種即時監(jiān)控案例來設(shè)定健康情況檢查端點(diǎn):

容器協(xié)調(diào)器和負(fù)載平衡器可以使用健康狀態(tài)探查,來檢查應(yīng)用程式的狀態(tài)。 例如,容器協(xié)調(diào)器可能會暫停輪流部署或重新啟動容器,來回應(yīng)失敗的健康狀態(tài)檢查。 負(fù)載平衡器可能會將流量從失敗的執(zhí)行個體路由傳送至狀況良好的執(zhí)行個體,來回應(yīng)狀況不良的應(yīng)用程式。 您可以監(jiān)控所使用記憶體、磁碟及其他實(shí)體伺服器資源的健康狀態(tài)。 健康狀態(tài)檢查可以測試應(yīng)用程式的相依性 (例如資料庫和外部服務(wù)端點(diǎn)),確認(rèn)其是否可用且正常運(yùn)作。

健康情況檢查通常會與外部監(jiān)控服務(wù)或容器協(xié)調(diào)器搭配使用,來檢查應(yīng)用程式的狀態(tài)。 將健康狀態(tài)檢查新增至應(yīng)用程式之前,請決定要使用的監(jiān)控系統(tǒng)。 監(jiān)控系統(tǒng)會指定要建立哪些健康狀態(tài)檢查類型,以及如何設(shè)定其端點(diǎn)。

基本健康狀態(tài)探查

對於許多應(yīng)用程式,報告應(yīng)用程式是否可處理要求的基本健康狀態(tài)探查組態(tài) (「活躍度」),便足以探索應(yīng)用程式的狀態(tài)。

基本設(shè)定會登錄健康情況檢查服務(wù),並呼叫健康情況檢查中介軟體以在具有健康情況回應(yīng)的 URL 端點(diǎn)做出回應(yīng)。 預(yù)設(shè)並未登錄特定健康狀態(tài)檢查來測試任何特定相依性或子系統(tǒng)。 如果應(yīng)用程式可以在健康情況端點(diǎn) URL 做出回應(yīng),則視為狀況良好。 預(yù)設(shè)回應(yīng)寫入器會將 HealthStatus 以純文字回應(yīng)形式寫入至用戶端。 HealthStatus 是 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy。

在 Program.cs 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 呼叫 MapHealthChecks 來建立健康情況檢查端點(diǎn)。

下列範(fàn)例會在 /healthz 建立健康情況檢查端點(diǎn):

var builder = WebApplication.CreateBuilder(args); builder.Services.AddHealthChecks(); var app = builder.Build(); app.MapHealthChecks("/healthz"); app.Run();

Docker HEALTHCHECK

Docker 提供內(nèi)建 HEALTHCHECK 指示詞,可用來檢查使用基本健康狀態(tài)檢查組態(tài)的應(yīng)用程式狀態(tài):

HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit

上述範(fàn)例會使用 curl,以在 /healthz 針對健康情況檢查端點(diǎn)提出 HTTP 要求。 curl 未包括在 .NET Linux 容器映像中,但可以在 Dockerfile 中安裝必要套件來進(jìn)行新增。 根據(jù) Alpine Linux 來使用映像的容器可以使用所包括的 wget 來取代 curl。

建立健康狀態(tài)檢查

健康狀態(tài)檢查是藉由實(shí)作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態(tài)為 Healthy、Degraded 或 Unhealthy 的 HealthCheckResult。 結(jié)果會寫成具有可設(shè)定狀態(tài)碼的純文字回應(yīng)。 健康情況檢查選項(xiàng)小節(jié)中會描述設(shè)定。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。

下列範(fàn)例示範(fàn)健康情況檢查的配置:

public class SampleHealthCheck : IHealthCheck { public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { var isHealthy = true; // ... if (isHealthy) { return Task.FromResult( HealthCheckResult.Healthy("A healthy result.")); } return Task.FromResult( new HealthCheckResult( context.Registration.FailureStatus, "An unhealthy result.")); } }

健康情況檢查的邏輯放在 CheckHealthAsync 方法中。 上述範(fàn)例會將虛擬變數(shù) isHealthy 設(shè)定為 true。 如果 isHealthy 的值設(shè)定為 false,則會傳回 HealthCheckRegistration.FailureStatus 狀態(tài)。

如果 CheckHealthAsync 在檢查期間擲回例外狀況,則會傳回其 HealthReportEntry.Status 設(shè)定為 FailureStatus 的新 HealthReportEntry。 此狀態(tài)是由 AddCheck 所定義 (請參閱登錄健康情況檢查服務(wù)一節(jié)),並包括造成檢查失敗的內(nèi)部例外狀況。 Description 會設(shè)定為例外狀況的訊息。

登錄健康狀態(tài)檢查服務(wù)

若要登錄健康情況檢查服務(wù),請在 Program.cs 中呼叫 AddCheck:

builder.Services.AddHealthChecks() .AddCheck<SampleHealthCheck>("Sample");

下列範(fàn)例中所顯示的 AddCheck 多載會設(shè)定在健康狀態(tài)檢查報告失敗時所要報告的失敗狀態(tài) (HealthStatus)。 如果將失敗狀態(tài)設(shè)定為 null (預(yù)設(shè)),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態(tài)檢查實(shí)作採用此設(shè)定,則當(dāng)健康狀態(tài)檢查失敗時,應(yīng)用程式就會強(qiáng)制程式庫指出失敗狀態(tài)。

「標(biāo)記」可以用來篩選健康情況檢查。 標(biāo)記會在篩選健康情況檢查小節(jié)中予以描述。

builder.Services.AddHealthChecks() .AddCheck<SampleHealthCheck>( "Sample", failureStatus: HealthStatus.Degraded, tags: new[] { "sample" });

AddCheck 也可以執(zhí)行匿名函式。 在下列範(fàn)例中,健康情況檢查一律會傳回狀況良好結(jié)果:

builder.Services.AddHealthChecks() .AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));

呼叫 AddTypeActivatedCheck,以將引數(shù)傳遞至健康情況檢查實(shí)作。 在下列範(fàn)例中,啟用類型的健康情況檢查會在其建構(gòu)函式中接受整數(shù)和字串:

public class SampleHealthCheckWithArgs : IHealthCheck { private readonly int _arg1; private readonly string _arg2; public SampleHealthCheckWithArgs(int arg1, string arg2) => (_arg1, _arg2) = (arg1, arg2); public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { // ... return Task.FromResult(HealthCheckResult.Healthy("A healthy result.")); } }

若要登錄上述健康情況檢查,請使用傳遞為引數(shù)的整數(shù)和字串來呼叫 AddTypeActivatedCheck:

builder.Services.AddHealthChecks() .AddTypeActivatedCheck<SampleHealthCheckWithArgs>( "Sample", failureStatus: HealthStatus.Degraded, tags: new[] { "sample" }, args: new object[] { 1, "Arg" });

使用健康情況檢查路由傳送

在 Program.cs 中,使用端點(diǎn) URL 或相對路徑以在端點(diǎn)建立器上呼叫 MapHealthChecks:

app.MapHealthChecks("/healthz");

需要主機(jī)

呼叫 RequireHost,以將一或多個允許的主機(jī)指定給健康情況檢查端點(diǎn)。 主機(jī)應(yīng)該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機(jī):

app.MapHealthChecks("/healthz") .RequireHost("www.contoso.com:5001");

若要限制健康情況檢查端點(diǎn)只在特定連接埠上回應(yīng),請在 RequireHost 呼叫中指定連接埠。 此方式通常用於容器環(huán)境,以公開監(jiān)控服務(wù)的連接埠:

app.MapHealthChecks("/healthz") .RequireHost("*:5001");

若要防止未經(jīng)授權(quán)的用戶端詐騙連接埠,請呼叫 RequireAuthorization:

app.MapHealthChecks("/healthz") .RequireHost("*:5001") .RequireAuthorization();

如需詳細(xì)資訊,請參閱具有 RequireHost 之路由中的主機(jī)比對。

需要授權(quán)

呼叫 RequireAuthorization,以在健康情況檢查要求端點(diǎn)上執(zhí)行授權(quán)中介軟體。 RequireAuthorization 多載接受一或多個授權(quán)原則。 如果未提供原則,則會使用預(yù)設(shè)授權(quán)原則:

app.MapHealthChecks("/healthz") .RequireAuthorization();

啟用跨原始來源要求 (CORS)

雖然從瀏覽器手動執(zhí)行健康情況檢查不是常見案例,但是您可以在健康情況檢查端點(diǎn)上呼叫 RequireCors,以啟用 CORS 中介軟體。 RequireCors 多載接受 CORS 原則建立器委派 (CorsPolicyBuilder) 或原則名稱。 如需詳細(xì)資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。

健康狀態(tài)檢查選項(xiàng)

HealthCheckOptions 讓您有機(jī)會自訂健康狀態(tài)檢查行為:

篩選健康狀態(tài)檢查 自訂 HTTP 狀態(tài)碼 隱藏快取標(biāo)頭 自訂輸出

篩選健康狀態(tài)檢查

根據(jù)預(yù)設(shè),健康情況檢查中介軟體會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行健康狀態(tài)檢查子集,請對 Predicate 選項(xiàng)提供傳回布林值的函式。

下列範(fàn)例會篩選健康情況檢查,以只執(zhí)行已標(biāo)記 sample 的檢查:

app.MapHealthChecks("/healthz", new HealthCheckOptions { Predicate = healthCheck => healthCheck.Tags.Contains("sample") });

自訂 HTTP 狀態(tài)碼

您可以使用 ResultStatusCodes 來自訂健康狀態(tài)與 HTTP 狀態(tài)碼的對應(yīng)。 下列 StatusCodes 指派是中介軟體所使用的預(yù)設(shè)值。 變更狀態(tài)碼值,以符合您的需求:

app.MapHealthChecks("/healthz", new HealthCheckOptions { ResultStatusCodes = { [HealthStatus.Healthy] = StatusCodes.Status200OK, [HealthStatus.Degraded] = StatusCodes.Status200OK, [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable } });

隱藏快取標(biāo)頭

AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標(biāo)頭新增至探查回應(yīng),以防止回應(yīng)快取。 如果值為 false (預(yù)設(shè)),則中介軟體會設(shè)定或覆寫 Cache-Control、Expires 和 Pragma 標(biāo)頭,以防止回應(yīng)快取。 如果值為 true,則中介軟體不會修改回應(yīng)的快取標(biāo)頭:

app.MapHealthChecks("/healthz", new HealthCheckOptions { AllowCachingResponses = true });

自訂輸出

若要自訂健康情況檢查報告的輸出,請將 HealthCheckOptions.ResponseWriter 屬性設(shè)定為可寫入回應(yīng)的委派:

app.MapHealthChecks("/healthz", new HealthCheckOptions { ResponseWriter = WriteResponse });

預(yù)設(shè)委派會使用字串值 HealthReport.Status 寫入基本純文字回應(yīng)。 下列自訂委派會使用 System.Text.Json來輸出自訂 JSON 回應(yīng):

private static Task WriteResponse(HttpContext context, HealthReport healthReport) { context.Response.ContentType = "application/json; charset=utf-8"; var options = new JsonWriterOptions { Indented = true }; using var memoryStream = new MemoryStream(); using (var jsonWriter = new Utf8JsonWriter(memoryStream, options)) { jsonWriter.WriteStartObject(); jsonWriter.WriteString("status", healthReport.Status.ToString()); jsonWriter.WriteStartObject("results"); foreach (var healthReportEntry in healthReport.Entries) { jsonWriter.WriteStartObject(healthReportEntry.Key); jsonWriter.WriteString("status", healthReportEntry.Value.Status.ToString()); jsonWriter.WriteString("description", healthReportEntry.Value.Description); jsonWriter.WriteStartObject("data"); foreach (var item in healthReportEntry.Value.Data) { jsonWriter.WritePropertyName(item.Key); JsonSerializer.Serialize(jsonWriter, item.Value, item.Value?.GetType() ?? typeof(object)); } jsonWriter.WriteEndObject(); jsonWriter.WriteEndObject(); } jsonWriter.WriteEndObject(); jsonWriter.WriteEndObject(); } return context.Response.WriteAsync( Encoding.UTF8.GetString(memoryStream.ToArray())); }

健康情況檢查 API 未提供複雜 JSON 傳回格式的內(nèi)建支援,因?yàn)榇烁袷绞悄x擇的監(jiān)控系統(tǒng)所特有。 視需要,自訂上述範(fàn)例中的回應(yīng)。 如需使用 System.Text.Json進(jìn)行 JSON 序列化的詳細(xì)資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。

資料庫探查

健康狀態(tài)檢查可指定資料庫查詢以布林測試方式來執(zhí)行,藉此指出資料庫是否正?;貞?yīng)。

AspNetCore.Diagnostics.HealthChecks,一種適用於 ASP.NET Core 應(yīng)用程式的健康情況檢查程式庫,包括針對 SQL Server 資料庫所執(zhí)行的健康情況檢查。 AspNetCore.Diagnostics.HealthChecks 會對資料庫執(zhí)行 SELECT 1 查詢,以確認(rèn)資料庫連線狀況良好。

警告

使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風(fēng)險。 在大部分情況下,不需要執(zhí)行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發(fā)現(xiàn)有必要執(zhí)行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1。

若要使用此 SQL Server 健康情況檢查,請包括 AspNetCore.HealthChecks.SqlServer NuGet 套件的套件參考。 下列範(fàn)例會登錄 SQL Server 健康情況檢查:

var conStr = builder.Configuration.GetConnectionString("DefaultConnection"); if (string.IsNullOrEmpty(conStr)) { throw new InvalidOperationException( "Could not find a connection string named 'DefaultConnection'."); } builder.Services.AddHealthChecks() .AddSqlServer(conStr);

Entity Framework Core DbContext 探查

DbContext 檢查會確認(rèn)應(yīng)用程式是否可以與針對 EF CoreDbContext 所設(shè)定的資料庫通訊。 應(yīng)用程式支援 DbContext 檢查:

使用 Entity Framework (EF) Core。 包括 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore NuGet 套件的套件參考。

AddDbContextCheck 會登錄 DbContext 的健康狀態(tài)檢查。 DbContext 會以 TContext 形式提供給方法。 多載可用來設(shè)定失敗狀態(tài)、標(biāo)籤和自訂測試查詢。

預(yù)設(shè)情況:

DbContextHealthCheck 會呼叫 EF Core 的 CanConnectAsync 方法。 您可以自訂使用 AddDbContextCheck 方法多載檢查健康狀態(tài)時所要執(zhí)行的作業(yè)。 健康狀態(tài)檢查的名稱是 TContext 類型的名稱。

下列範(fàn)例會登錄 DbContext 和相關(guān)聯(lián)的 DbContextHealthCheck:

builder.Services.AddDbContext<SampleDbContext>(options => options.UseSqlServer( builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddHealthChecks() .AddDbContextCheck<SampleDbContext>();

個別的整備度與活躍度探查

在某些裝載案例中,會使用一組健康情況檢查來區(qū)分兩個應(yīng)用程式狀態(tài):

「整備」指出應(yīng)用程式是否正在正常執(zhí)行,但尚未準(zhǔn)備好接收要求。 「活躍度」指出應(yīng)用程式是否已當(dāng)機(jī),而且必須重新予以啟動。

請考慮下列範(fàn)例:應(yīng)用程式在準(zhǔn)備好處理要求之前必須下載大型設(shè)定檔。 如果初始下載失敗,則我們不想要重新啟動應(yīng)用程式,因?yàn)閼?yīng)用程式可以重試下載檔案數(shù)次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執(zhí)行其他檢查。 我們也想要防止在設(shè)定檔下載成功之前將要求傳送至應(yīng)用程式。 除非下載成功,而且應(yīng)用程式準(zhǔn)備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」?fàn)顟B(tài)。

下列背景工作會模擬大約需要 15 秒的啟動處理序。 完成後,工作會將 StartupHealthCheck.StartupCompleted 屬性設(shè)定為 True:

public class StartupBackgroundService : BackgroundService { private readonly StartupHealthCheck _healthCheck; public StartupBackgroundService(StartupHealthCheck healthCheck) => _healthCheck = healthCheck; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // Simulate the effect of a long-running task. await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken); _healthCheck.StartupCompleted = true; } }

StartupHealthCheck 會報告長時間執(zhí)行的啟動工作完成,並公開背景服務(wù)所設(shè)定的 StartupCompleted 屬性:

public class StartupHealthCheck : IHealthCheck { private volatile bool _isReady; public bool StartupCompleted { get => _isReady; set => _isReady = value; } public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { if (StartupCompleted) { return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed.")); } return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running.")); } }

健康狀態(tài)檢查是 Program.cs 中使用 AddCheck 隨託管服務(wù)一起登錄。 因?yàn)樗b載服務(wù)必須在健康情況檢查上設(shè)定此屬性,所以也會在服務(wù)容器中將健康情況檢查登錄為單一資料庫:

builder.Services.AddHostedService<StartupBackgroundService>(); builder.Services.AddSingleton<StartupHealthCheck>(); builder.Services.AddHealthChecks() .AddCheck<StartupHealthCheck>( "Startup", tags: new[] { "ready" });

若要建立兩個不同的健康情況檢查端點(diǎn),請呼叫 MapHealthChecks 兩次:

app.MapHealthChecks("/healthz/ready", new HealthCheckOptions { Predicate = healthCheck => healthCheck.Tags.Contains("ready") }); app.MapHealthChecks("/healthz/live", new HealthCheckOptions { Predicate = _ => false });

上述範(fàn)例會建立下列健康情況檢查端點(diǎn):

/healthz/ready 用於整備檢查。 整備檢查會將健康情況檢查篩選為已標(biāo)記 ready 的檢查。 /healthz/live 用於活躍度檢查。 活躍度檢查會在 HealthCheckOptions.Predicate 委派中傳回 false,以篩選出所有健康情況檢查。 如需篩選健康情況檢查的詳細(xì)資訊,請參閱本文中的篩選健康情況檢查。

啟動工作完成之前,/healthz/ready 端點(diǎn)會回報 Unhealthy 狀態(tài)。 啟動工作完成之後,此端點(diǎn)會回報 Healthy 狀態(tài)。 /healthz/live 端點(diǎn)會排除所有檢查,並將所有呼叫的狀態(tài)都回報為 Healthy。

Kubernetes 範(fàn)例

使用個別的整備度與活躍度檢查在 Kubernetes 之類的環(huán)境中很有用。 在 Kubernetes 中,應(yīng)用程式可能需要先執(zhí)行耗時的啟動工作,才能接受要求 (例如基礎(chǔ)資料庫可用性測試)。 使用個別的檢查可讓協(xié)調(diào)器區(qū)分應(yīng)用程式是否為正常運(yùn)作但尚未準(zhǔn)備好,或應(yīng)用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細(xì)資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設(shè)定活躍度與整備度探查)。

下列範(fàn)例示範(fàn) Kubernetes 整備度探查組態(tài):

spec: template: spec: readinessProbe: # an http probe httpGet: path: /healthz/ready port: 80 # length of time to wait for a pod to initialize # after pod startup, before applying health checking initialDelaySeconds: 30 timeoutSeconds: 1 ports: - containerPort: 80

發(fā)佈健康狀態(tài)檢查程式庫

若要發(fā)佈健康狀態(tài)檢查作為程式庫:

寫入健康狀態(tài)檢查,將 IHealthCheck 介面當(dāng)做獨(dú)立類別來實(shí)作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項(xiàng)來存取組態(tài)資料。

使用取用應(yīng)用程式在其 Program.cs 方法中呼叫的參數(shù),來寫入延伸模組。 請考慮下列範(fàn)例健康情況檢查,而此檢查接受 arg1 和 arg2 作為建構(gòu)函式參數(shù):

public SampleHealthCheckWithArgs(int arg1, string arg2) => (_arg1, _arg2) = (arg1, arg2);

上述簽章指出健康情況檢查需要自訂資料,才能處理健康情況檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態(tài)檢查時,用來建立健康狀態(tài)檢查執(zhí)行個體。 在下列範(fàn)例中,呼叫端會指定:

arg1:健康情況檢查的整數(shù)資料點(diǎn)。 arg2:健康情況檢查的字串引數(shù)。 name:選用的健康情況檢查名稱。 如果 null,則會使用預(yù)設(shè)值。 failureStatus:選用的 HealthStatus,其回報失敗狀態(tài)。 如果為 null,則會使用 HealthStatus.Unhealthy。 tags:標(biāo)記的選用 IEnumerable<string> 集合。

public static class SampleHealthCheckBuilderExtensions { private const string DefaultName = "Sample"; public static IHealthChecksBuilder AddSampleHealthCheck( this IHealthChecksBuilder healthChecksBuilder, int arg1, string arg2, string? name = null, HealthStatus? failureStatus = null, IEnumerable<string>? tags = default) { return healthChecksBuilder.Add( new HealthCheckRegistration( name ?? DefaultName, _ => new SampleHealthCheckWithArgs(arg1, arg2), failureStatus, tags)); } }

健康狀態(tài)檢查發(fā)行者

當(dāng) IHealthCheckPublisher 新增至服務(wù)容器時,健康狀態(tài)檢查系統(tǒng)會定期執(zhí)行健康狀態(tài)檢查,並呼叫 PublishAsync 傳回結(jié)果。 此處理序適用於推送型健康情況監(jiān)控系統(tǒng)案例,而此案例預(yù)期每個處理序都會定期呼叫監(jiān)控系統(tǒng)來判斷健康情況。

HealthCheckPublisherOptions 可讓您設(shè)定:

Delay:初始延遲會在應(yīng)用程式啟動之後且執(zhí)行 IHealthCheckPublisher 執(zhí)行個體之前套用。 啟動後就會套用延遲,但不會套用至後面的反覆項(xiàng)目。 預(yù)設(shè)值是五秒鐘。 Period:IHealthCheckPublisher 執(zhí)行的期間。 預(yù)設(shè)值為 30 秒。 Predicate:如果 Predicate 為 null (預(yù)設(shè)),則健康情況檢查發(fā)行者服務(wù)會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行一部分的健康狀態(tài)檢查,請?zhí)峁┛珊Y選該組檢查的函式。 每個期間都會評估該述詞。 Timeout:執(zhí)行所有 IHealthCheckPublisher 執(zhí)行個體之健康情況檢查的逾時。 若要在沒有逾時的情況下執(zhí)行,請使用 InfiniteTimeSpan。 預(yù)設(shè)值為 30 秒。

下列範(fàn)例示範(fàn)健康情況發(fā)行者的配置:

public class SampleHealthCheckPublisher : IHealthCheckPublisher { public Task PublishAsync(HealthReport report, CancellationToken cancellationToken) { if (report.Status == HealthStatus.Healthy) { // ... } else { // ... } return Task.CompletedTask; } }

HealthCheckPublisherOptions 類別提供屬性來設(shè)定健康情況檢查發(fā)行者的行為。

下列範(fàn)例會將健康情況檢查發(fā)行者登錄為單一資料庫,並設(shè)定 HealthCheckPublisherOptions:

builder.Services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(2); options.Predicate = healthCheck => healthCheck.Tags.Contains("sample"); }); builder.Services.AddSingleton<IHealthCheckPublisher, SampleHealthCheckPublisher>();

AspNetCore.Diagnostics.HealthChecks:

包括數(shù)個系統(tǒng)的發(fā)行者,包括 Application Insights。 受 Microsoft 維護(hù)或支援。

個別的 HealthChecks

Delay 和 Period 可以在每個 HealthCheckRegistration 上個別設(shè)定。 當(dāng)您想要以與 HealthCheckPublisherOptions 中所設(shè)定的期間不同的速率執(zhí)行一些健康情況檢查時,這非常有用。

下列程式碼會設(shè)定 SampleHealthCheck1 的 Delay 和 Period:

var builder = WebApplication.CreateBuilder(args); builder.Services.AddHealthChecks() .Add(new HealthCheckRegistration( name: "SampleHealthCheck1", instance: new SampleHealthCheck(), failureStatus: null, tags: null, timeout: default) { Delay = TimeSpan.FromSeconds(40), Period = TimeSpan.FromSeconds(30) }); var app = builder.Build(); app.MapHealthChecks("/healthz"); app.Run();

相依性插入和健康情況檢查

您可以使用相依性插入來取用健康情況檢查類別內(nèi)特定 Type 的執(zhí)行個體。 相依性插入適用於將選項(xiàng)或全域設(shè)定插入至健康情況檢查。 使用相依性插入「不」是設(shè)定健康情況檢查的常見案例。 通常,每個健康情況檢查都是專屬於實(shí)際測試,並且使用 IHealthChecksBuilder 擴(kuò)充方法進(jìn)行設(shè)定。

下列範(fàn)例顯示可透過相依性插入來擷取設(shè)定物件的範(fàn)例健康情況檢查:

public class SampleHealthCheckWithDI : IHealthCheck { private readonly SampleHealthCheckWithDiConfig _config; public SampleHealthCheckWithDI(SampleHealthCheckWithDiConfig config) => _config = config; public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { var isHealthy = true; // use _config ... if (isHealthy) { return Task.FromResult( HealthCheckResult.Healthy("A healthy result.")); } return Task.FromResult( new HealthCheckResult( context.Registration.FailureStatus, "An unhealthy result.")); } }

SampleHealthCheckWithDiConfig 和健康情況檢查需要新增至服務(wù)容器:

builder.Services.AddSingleton<SampleHealthCheckWithDiConfig>(new SampleHealthCheckWithDiConfig { BaseUriToCheck = new Uri("https://sample.contoso.com/api/") }); builder.Services.AddHealthChecks() .AddCheck<SampleHealthCheckWithDI>( "With Dependency Injection", tags: new[] { "inject" });

UseHealthChecks 與MapHealthChecks

有兩種方式可讓呼叫端存取健康情況檢查:

UseHealthChecks 會登錄中介軟體來處理中介軟體管線中的健康情況檢查要求。 MapHealthChecks 會登錄健康情況檢查端點(diǎn)。 端點(diǎn)會與應(yīng)用程式中的其他端點(diǎn)進(jìn)行比對和執(zhí)行。

使用 MapHealthChecks 優(yōu)於 UseHealthChecks 的優(yōu)點(diǎn)是能夠使用端點(diǎn)感知中介軟體 (例如授權(quán)),並更精細(xì)地控制比對原則。 使用 UseHealthChecks 優(yōu)於 MapHealthChecks 的主要優(yōu)點(diǎn)是確切控制中介軟體管線中執(zhí)行健康情況檢查的位置。

UseHealthChecks:

在要求符合健康情況檢查端點(diǎn)時終止管線。 最短線路可避免不必要的工作,因此經(jīng)常使用 (例如記錄和其他中介軟體)。 主要用於在管線中設(shè)定健康情況檢查中介軟體。 可以比對連接埠上的任何路徑與 null 或空白 PathString。 允許在針對所指定連接埠所提出的任何要求上執(zhí)行健康情況檢查。 原始程式碼

MapHealthChecks 允許:

呼叫 ShortCircuit,以在要求符合健康情況檢查端點(diǎn)時終止管線。 例如: app.MapHealthChecks("/healthz").ShortCircuit(); 。 如需詳細(xì)資訊,請參閱路由之後尋找中介軟體的最短路徑。 對應(yīng)特定路由或端點(diǎn)以進(jìn)行健康情況檢查。 自訂可存取健康情況檢查端點(diǎn)的 URL 或路徑。 使用不同的路由或設(shè)定來對應(yīng)多個健康情況檢查端點(diǎn)。 多個端點(diǎn)支援: 針對不同類型的健康情況檢查或元件啟用不同的端點(diǎn)。 用來區(qū)分應(yīng)用程式健康情況的不同層面,或?qū)⑻囟ㄔO(shè)定套用至健康情況檢查的子集。 原始程式碼

其他資源

檢視或下載範(fàn)例程式碼 (英文) (如何下載)

ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應(yīng)用程式基礎(chǔ)結(jié)構(gòu)元件的健康情況。

應(yīng)用程式會將健康狀態(tài)檢查公開為 HTTP 端點(diǎn)。 您可以針對各種即時監(jiān)控案例來設(shè)定健康情況檢查端點(diǎn):

容器協(xié)調(diào)器和負(fù)載平衡器可以使用健康狀態(tài)探查,來檢查應(yīng)用程式的狀態(tài)。 例如,容器協(xié)調(diào)器可能會暫停輪流部署或重新啟動容器,來回應(yīng)失敗的健康狀態(tài)檢查。 負(fù)載平衡器可能會將流量從失敗的執(zhí)行個體路由傳送至狀況良好的執(zhí)行個體,來回應(yīng)狀況不良的應(yīng)用程式。 您可以監(jiān)控所使用記憶體、磁碟及其他實(shí)體伺服器資源的健康狀態(tài)。 健康狀態(tài)檢查可以測試應(yīng)用程式的相依性 (例如資料庫和外部服務(wù)端點(diǎn)),確認(rèn)其是否可用且正常運(yùn)作。

檢視或下載範(fàn)例程式碼 (英文) (如何下載)

範(fàn)例應(yīng)用程式包括本文中所述的案例範(fàn)例。 若要在指定的案例中執(zhí)行範(fàn)例應(yīng)用程式,請在命令殼層中使用來自專案資料夾的 dotnet run 命令。 如需如何使用範(fàn)例應(yīng)用程式的詳細(xì)資料,請參閱範(fàn)例應(yīng)用程式的 README.md 檔案和本文中的案例描述。

必要條件

健康情況檢查通常會與外部監(jiān)控服務(wù)或容器協(xié)調(diào)器搭配使用,來檢查應(yīng)用程式的狀態(tài)。 將健康狀態(tài)檢查新增至應(yīng)用程式之前,請決定要使用的監(jiān)控系統(tǒng)。 監(jiān)控系統(tǒng)會指定要建立哪些健康狀態(tài)檢查類型,以及如何設(shè)定其端點(diǎn)。

ASP.NET Core 應(yīng)用程式會隱含參考 Microsoft.AspNetCore.Diagnostics.HealthChecks 套件。 若要使用 Entity Framework Core 來執(zhí)行健康情況檢查,請新增 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore 套件的參考。

範(fàn)例應(yīng)用程式提供啟動程式碼,來示範(fàn)數(shù)個案例的健康狀態(tài)檢查。 資料庫探查案例使用 AspNetCore.Diagnostics.HealthChecks 來檢查資料庫連線的健康情況。 DbContext 探查案例使用 EF CoreDbContext 來檢查資料庫。 為了探索資料庫案例,範(fàn)例應(yīng)用程式會:

建立資料庫,並在 appsettings.json 檔案中提供其連接字串。 在其專案檔中具有下列套件參考: AspNetCore.HealthChecks.SqlServer Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore

另一個健康狀態(tài)檢查案例示範(fàn)如何將健康狀態(tài)檢查篩選至管理連接埠。 範(fàn)例應(yīng)用程式需要您建立 Properties/launchSettings.json 檔案,而此檔案包括管理 URL 和管理連接埠。 如需詳細(xì)資訊,請參閱依連接埠篩選一節(jié)。

基本健康狀態(tài)探查

對於許多應(yīng)用程式,報告應(yīng)用程式是否可處理要求的基本健康狀態(tài)探查組態(tài) (「活躍度」),便足以探索應(yīng)用程式的狀態(tài)。

基本設(shè)定會登錄健康情況檢查服務(wù),並呼叫健康情況檢查中介軟體以在具有健康情況回應(yīng)的 URL 端點(diǎn)做出回應(yīng)。 預(yù)設(shè)並未登錄特定健康狀態(tài)檢查來測試任何特定相依性或子系統(tǒng)。 如果應(yīng)用程式可以在健康情況端點(diǎn) URL 做出回應(yīng),則視為狀況良好。 預(yù)設(shè)回應(yīng)寫入器會將狀態(tài) (HealthStatus) 以純文字回應(yīng)形式回寫至用戶端,指出 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy 狀態(tài)。

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 在 Startup.Configure 中呼叫 MapHealthChecks,以建立健康情況檢查端點(diǎn)。

在範(fàn)例應(yīng)用程式中,是在 /health (BasicStartup.cs) 建立健康情況檢查端點(diǎn):

public class BasicStartup { public void ConfigureServices(IServiceCollection services) { services.AddHealthChecks(); } public void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }); } }

若要使用範(fàn)例應(yīng)用程式執(zhí)行基本組態(tài)案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario basic

Docker 範(fàn)例

Docker 提供內(nèi)建 HEALTHCHECK 指示詞,可用來檢查使用基本健康狀態(tài)檢查組態(tài)的應(yīng)用程式狀態(tài):

HEALTHCHECK CMD curl --fail http://localhost:5000/health || exit

建立健康狀態(tài)檢查

健康狀態(tài)檢查是藉由實(shí)作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態(tài)為 Healthy、Degraded 或 Unhealthy 的 HealthCheckResult。 結(jié)果會寫成具有可設(shè)定狀態(tài)碼的純文字回應(yīng) (健康狀態(tài)檢查選項(xiàng)一節(jié)中將說明如何進(jìn)行組態(tài))。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。

下列 ExampleHealthCheck 類別示範(fàn)健康情況檢查的配置。 健康情況檢查邏輯放在 CheckHealthAsync 方法中。 下列範(fàn)例會將虛擬變數(shù) healthCheckResultHealthy 設(shè)定為 true。 如果 healthCheckResultHealthy 的值設(shè)定為 false,則會傳回 HealthCheckRegistration.FailureStatus 狀態(tài)。

public class ExampleHealthCheck : IHealthCheck { public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { var healthCheckResultHealthy = true; if (healthCheckResultHealthy) { return Task.FromResult( HealthCheckResult.Healthy("A healthy result.")); } return Task.FromResult( new HealthCheckResult(context.Registration.FailureStatus, "An unhealthy result.")); } }

如果 CheckHealthAsync 在檢查期間擲回例外狀況,則會傳回其 HealthReportEntry.Status 設(shè)定為 FailureStatus 的新 HealthReportEntry (這由 AddCheck 所定義) (請參閱登錄健康情況檢查服務(wù)小節(jié)),並包括最初造成檢查失敗的內(nèi)部例外狀況。 Description 會設(shè)定為例外狀況的訊息。

登錄健康狀態(tài)檢查服務(wù)

在 Startup.ConfigureServices 中使用 AddCheck,以將 ExampleHealthCheck 類型新增至健康情況檢查服務(wù):

services.AddHealthChecks() .AddCheck<ExampleHealthCheck>("example_health_check");

下列範(fàn)例中所顯示的 AddCheck 多載會設(shè)定在健康狀態(tài)檢查報告失敗時所要報告的失敗狀態(tài) (HealthStatus)。 如果將失敗狀態(tài)設(shè)定為 null (預(yù)設(shè)),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態(tài)檢查實(shí)作採用此設(shè)定,則當(dāng)健康狀態(tài)檢查失敗時,應(yīng)用程式就會強(qiáng)制程式庫指出失敗狀態(tài)。

您可以使用「標(biāo)籤」來篩選健康狀態(tài)檢查 (篩選健康狀態(tài)檢查一節(jié)中將進(jìn)一步說明)。

services.AddHealthChecks() .AddCheck<ExampleHealthCheck>( "example_health_check", failureStatus: HealthStatus.Degraded, tags: new[] { "example" });

AddCheck 也可以執(zhí)行匿名函式。 在下列範(fàn)例中,健康狀態(tài)檢查名稱指定為 Example,且檢查一律會傳回狀況良好狀態(tài):

services.AddHealthChecks() .AddCheck("Example", () => HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });

呼叫 AddTypeActivatedCheck,以將引數(shù)傳遞至健康情況檢查實(shí)作。 在下列範(fàn)例中,TestHealthCheckWithArgs 接受在呼叫 CheckHealthAsync 時使用整數(shù)和字串:

private class TestHealthCheckWithArgs : IHealthCheck { public TestHealthCheckWithArgs(int i, string s) { I = i; S = s; } public int I { get; set; } public string S { get; set; } public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { ... } }

使用傳遞至實(shí)作的整數(shù)和字串來呼叫 AddTypeActivatedCheck,以登錄 TestHealthCheckWithArgs:

services.AddHealthChecks() .AddTypeActivatedCheck<TestHealthCheckWithArgs>( "test", failureStatus: HealthStatus.Degraded, tags: new[] { "example" }, args: new object[] { 5, "string" });

使用健康情況檢查路由傳送

在 Startup.Configure 中,使用端點(diǎn) URL 或相對路徑以在端點(diǎn)建立器上呼叫 MapHealthChecks:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); });

需要主機(jī)

呼叫 RequireHost,以將一或多個允許的主機(jī)指定給健康情況檢查端點(diǎn)。 主機(jī)應(yīng)該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機(jī)。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001"); });

如需詳細(xì)資訊,請參閱依連接埠篩選一節(jié)。

需要授權(quán)

呼叫 RequireAuthorization,以在健康情況檢查要求端點(diǎn)上執(zhí)行授權(quán)中介軟體。 RequireAuthorization 多載接受一或多個授權(quán)原則。 如果未提供原則,則會使用預(yù)設(shè)授權(quán)原則。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health").RequireAuthorization(); });

啟用跨原始來源要求 (CORS)

雖然從瀏覽器手動執(zhí)行健康情況檢查不是常見使用案例,但是您可以在健康情況檢查端點(diǎn)上呼叫 RequireCors,以啟用 CORS 中介軟體。 RequireCors 多載接受 CORS 原則建立器委派 (CorsPolicyBuilder) 或原則名稱。 如果未提供原則,則會使用預(yù)設(shè) CORS 原則。 如需詳細(xì)資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。

健康狀態(tài)檢查選項(xiàng)

HealthCheckOptions 讓您有機(jī)會自訂健康狀態(tài)檢查行為:

篩選健康狀態(tài)檢查 自訂 HTTP 狀態(tài)碼 隱藏快取標(biāo)頭 自訂輸出

篩選健康狀態(tài)檢查

根據(jù)預(yù)設(shè),健康情況檢查中介軟體會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行健康狀態(tài)檢查子集,請對 Predicate 選項(xiàng)提供傳回布林值的函式。 在下列範(fàn)例中,會依函式條件陳述式中的標(biāo)籤 (bar_tag) 篩選出 Bar 健康狀態(tài)檢查。只有在健康狀態(tài)檢查的 Tags 屬性符合 foo_tag 或 baz_tag 時,才傳回 true:

在 Startup.ConfigureServices 中:

services.AddHealthChecks() .AddCheck("Foo", () => HealthCheckResult.Healthy("Foo is OK!"), tags: new[] { "foo_tag" }) .AddCheck("Bar", () => HealthCheckResult.Unhealthy("Bar is unhealthy!"), tags: new[] { "bar_tag" }) .AddCheck("Baz", () => HealthCheckResult.Healthy("Baz is OK!"), tags: new[] { "baz_tag" });

在 Startup.Configure 中,Predicate 會篩選出「橫條圖」健康情況檢查。 只有 Foo 和 Baz 才能執(zhí)行:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { Predicate = (check) => check.Tags.Contains("foo_tag") || check.Tags.Contains("baz_tag") }); });

自訂 HTTP 狀態(tài)碼

您可以使用 ResultStatusCodes 來自訂健康狀態(tài)與 HTTP 狀態(tài)碼的對應(yīng)。 下列 StatusCodes 指派是中介軟體所使用的預(yù)設(shè)值。 請變更狀態(tài)碼值以符合您的需求。

在 Startup.Configure 中:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { ResultStatusCodes = { [HealthStatus.Healthy] = StatusCodes.Status200OK, [HealthStatus.Degraded] = StatusCodes.Status200OK, [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable } }); });

隱藏快取標(biāo)頭

AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標(biāo)頭新增至探查回應(yīng),以防止回應(yīng)快取。 如果值為 false (預(yù)設(shè)),則中介軟體會設(shè)定或覆寫 Cache-Control、Expires 和 Pragma 標(biāo)頭,以防止回應(yīng)快取。 如果值為 true,則中介軟體不會修改回應(yīng)的快取標(biāo)頭。

在 Startup.Configure 中:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { AllowCachingResponses = true }); });

自訂輸出

在 Startup.Configure 中,將 HealthCheckOptions.ResponseWriter 選項(xiàng)設(shè)定為撰寫回應(yīng)的委派:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { ResponseWriter = WriteResponse }); });

預(yù)設(shè)委派會使用字串值 HealthReport.Status 寫入基本純文字回應(yīng)。 下列自訂委派會輸出自訂 JSON 回應(yīng)。

範(fàn)例應(yīng)用程式中的第一個範(fàn)例示範(fàn)如何使用 System.Text.Json:

private static Task WriteResponse(HttpContext context, HealthReport result) { context.Response.ContentType = "application/json; charset=utf-8"; var options = new JsonWriterOptions { Indented = true }; using (var stream = new MemoryStream()) { using (var writer = new Utf8JsonWriter(stream, options)) { writer.WriteStartObject(); writer.WriteString("status", result.Status.ToString()); writer.WriteStartObject("results"); foreach (var entry in result.Entries) { writer.WriteStartObject(entry.Key); writer.WriteString("status", entry.Value.Status.ToString()); writer.WriteString("description", entry.Value.Description); writer.WriteStartObject("data"); foreach (var item in entry.Value.Data) { writer.WritePropertyName(item.Key); JsonSerializer.Serialize( writer, item.Value, item.Value?.GetType() ?? typeof(object)); } writer.WriteEndObject(); writer.WriteEndObject(); } writer.WriteEndObject(); writer.WriteEndObject(); } var json = Encoding.UTF8.GetString(stream.ToArray()); return context.Response.WriteAsync(json); } }

第二個範(fàn)例示範(fàn)如何使用 Newtonsoft.Json:

private static Task WriteResponse(HttpContext context, HealthReport result) { context.Response.ContentType = "application/json"; var json = new JObject( new JProperty("status", result.Status.ToString()), new JProperty("results", new JObject(result.Entries.Select(pair => new JProperty(pair.Key, new JObject( new JProperty("status", pair.Value.Status.ToString()), new JProperty("description", pair.Value.Description), new JProperty("data", new JObject(pair.Value.Data.Select( p => new JProperty(p.Key, p.Value)))))))))); return context.Response.WriteAsync( json.ToString(Formatting.Indented)); }

在範(fàn)例應(yīng)用程式中,註解化 CustomWriterStartup.cs 中的 SYSTEM_TEXT_JSON 前置處理器指示詞,以啟用 WriteResponse 的 Newtonsoft.Json 版本。

健康情況檢查 API 未提供複雜 JSON 傳回格式的內(nèi)建支援,因?yàn)榇烁袷绞悄x擇的監(jiān)控系統(tǒng)所特有。 視需要,自訂上述範(fàn)例中的回應(yīng)。 如需使用 System.Text.Json進(jìn)行 JSON 序列化的詳細(xì)資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。

資料庫探查

健康狀態(tài)檢查可指定資料庫查詢以布林測試方式來執(zhí)行,藉此指出資料庫是否正?;貞?yīng)。

範(fàn)例應(yīng)用程式使用 AspNetCore.Diagnostics.HealthChecks (一種適用於 ASP.NET Core 應(yīng)用程式的健康情況檢查程式庫),以在 SQL Server 資料庫上執(zhí)行健康情況檢查。 AspNetCore.Diagnostics.HealthChecks 會對資料庫執(zhí)行 SELECT 1 查詢,以確認(rèn)資料庫連線狀況良好。

警告

使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風(fēng)險。 在大部分情況下,不需要執(zhí)行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發(fā)現(xiàn)有必要執(zhí)行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1。

包括 AspNetCore.HealthChecks.SqlServer 的套件參考。

在範(fàn)例應(yīng)用程式的 appsettings.json 檔案中,提供有效的資料庫連接字串。 應(yīng)用程式使用名為 HealthCheckSample 的 SQL Server 資料庫:

{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\MSSQLLocalDB;Database=HealthCheckSample;Trusted_Connection=True;MultipleActiveResultSets=true;ConnectRetryCount=0" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" }, "Console": { "IncludeScopes": "true" } }, "AllowedHosts": "*" }

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 範(fàn)例應(yīng)用程式會使用資料庫連接字串 (DbHealthStartup.cs) 來呼叫 AddSqlServer 方法:

services.AddHealthChecks() .AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }

若要使用範(fàn)例應(yīng)用程式執(zhí)行資料庫探查案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario db

Entity Framework Core DbContext 探查

DbContext 檢查會確認(rèn)應(yīng)用程式是否可以與針對 EF CoreDbContext 所設(shè)定的資料庫通訊。 應(yīng)用程式支援 DbContext 檢查:

使用 Entity Framework (EF) Core。 包括 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore 的套件參考。

AddDbContextCheck<TContext> 會登錄 DbContext 的健康狀態(tài)檢查。 DbContext 會以 TContext 形式提供給方法。 多載可用來設(shè)定失敗狀態(tài)、標(biāo)籤和自訂測試查詢。

預(yù)設(shè)情況:

DbContextHealthCheck 會呼叫 EF Core 的 CanConnectAsync 方法。 您可以自訂使用 AddDbContextCheck 方法多載檢查健康狀態(tài)時所要執(zhí)行的作業(yè)。 健康狀態(tài)檢查的名稱是 TContext 類型的名稱。

在範(fàn)例應(yīng)用程式中,會將 AppDbContext 提供給 AddDbContextCheck,並在 Startup.ConfigureServices 中登錄為服務(wù) (DbContextHealthStartup.cs):

services.AddHealthChecks() .AddDbContextCheck<AppDbContext>(); services.AddDbContext<AppDbContext>(options => { options.UseSqlServer( Configuration["ConnectionStrings:DefaultConnection"]); });

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }

若要使用範(fàn)例應(yīng)用程式來執(zhí)行 DbContext 探查案例,請確認(rèn) SQL Server 執(zhí)行個體中沒有連接字串所指定的資料庫。 如果資料庫存在,請予以刪除。

在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario dbcontext

在應(yīng)用程式執(zhí)行之後,對瀏覽器中的 /health 端點(diǎn)提出要求來檢查健康狀態(tài)。 資料庫和 AppDbContext 不存在,因此應(yīng)用程式會提供下列回應(yīng):

Unhealthy

觸發(fā)範(fàn)例應(yīng)用程式以建立資料庫。 對 /createdatabase 提出要求。 應(yīng)用程式會回應(yīng):

Creating the database... Done! Navigate to /health to see the health status.

對 /health 端點(diǎn)提出要求。 資料庫和內(nèi)容存在,因此應(yīng)用程式會回應(yīng):

Healthy

觸發(fā)範(fàn)例應(yīng)用程式以刪除資料庫。 對 /deletedatabase 提出要求。 應(yīng)用程式會回應(yīng):

Deleting the database... Done! Navigate to /health to see the health status.

對 /health 端點(diǎn)提出要求。 應(yīng)用程式會提供狀況不良回應(yīng):

Unhealthy

個別的整備度與活躍度探查

在某些裝載案例中,會使用一組健康情況檢查來區(qū)分兩個應(yīng)用程式狀態(tài):

「整備」指出應(yīng)用程式是否正在正常執(zhí)行,但尚未準(zhǔn)備好接收要求。 「活躍度」指出應(yīng)用程式是否已當(dāng)機(jī),而且必須重新予以啟動。

請考慮下列範(fàn)例:應(yīng)用程式在準(zhǔn)備好處理要求之前必須下載大型設(shè)定檔。 如果初始下載失敗,則我們不想要重新啟動應(yīng)用程式,因?yàn)閼?yīng)用程式可以重試下載檔案數(shù)次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執(zhí)行其他檢查。 我們也想要防止在設(shè)定檔下載成功之前將要求傳送至應(yīng)用程式。 除非下載成功,而且應(yīng)用程式準(zhǔn)備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」?fàn)顟B(tài)。

範(fàn)例應(yīng)用程式包含健康狀態(tài)檢查,會在託管服務(wù)中長時間執(zhí)行的啟動工作完成時回報。 StartupHostedServiceHealthCheck 會公開 StartupTaskCompleted 屬性,而裝載的服務(wù)可以在其長時間執(zhí)行的工作完成時,將此屬性設(shè)定為 true (StartupHostedServiceHealthCheck.cs):

public class StartupHostedServiceHealthCheck : IHealthCheck { private volatile bool _startupTaskCompleted = false; public string Name => "slow_dependency_check"; public bool StartupTaskCompleted { get => _startupTaskCompleted; set => _startupTaskCompleted = value; } public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { if (StartupTaskCompleted) { return Task.FromResult( HealthCheckResult.Healthy("The startup task is finished.")); } return Task.FromResult( HealthCheckResult.Unhealthy("The startup task is still running.")); } }

裝載的服務(wù) (Services/StartupHostedService) 會啟動長時間執(zhí)行的背景工作。 工作完成時,StartupHostedServiceHealthCheck.StartupTaskCompleted 會設(shè)定為 true:

public class StartupHostedService : IHostedService, IDisposable { private readonly int _delaySeconds = 15; private readonly ILogger _logger; private readonly StartupHostedServiceHealthCheck _startupHostedServiceHealthCheck; public StartupHostedService(ILogger<StartupHostedService> logger, StartupHostedServiceHealthCheck startupHostedServiceHealthCheck) { _logger = logger; _startupHostedServiceHealthCheck = startupHostedServiceHealthCheck; } public Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Startup Background Service is starting."); // Simulate the effect of a long-running startup task. Task.Run(async () => { await Task.Delay(_delaySeconds * 1000); _startupHostedServiceHealthCheck.StartupTaskCompleted = true; _logger.LogInformation("Startup Background Service has started."); }); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("Startup Background Service is stopping."); return Task.CompletedTask; } public void Dispose() { } }

健康狀態(tài)檢查是 Startup.ConfigureServices 中使用 AddCheck 隨託管服務(wù)一起登錄。 因?yàn)樗b載服務(wù)必須在健康情況檢查上設(shè)定此屬性,所以也會在服務(wù)容器中登錄健康情況檢查 (LivenessProbeStartup.cs):

services.AddHostedService<StartupHostedService>(); services.AddSingleton<StartupHostedServiceHealthCheck>(); services.AddHealthChecks() .AddCheck<StartupHostedServiceHealthCheck>( "hosted_service_startup", failureStatus: HealthStatus.Degraded, tags: new[] { "ready" }); services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(2); options.Predicate = (check) => check.Tags.Contains("ready"); }); services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks。 在範(fàn)例應(yīng)用程式中,是在下列位置建立健康情況檢查端點(diǎn):

/health/ready 用於整備檢查。 整備度檢查使用 ready 標(biāo)籤來篩選健康狀態(tài)檢查。 /health/live 用於活躍度檢查。 活躍度檢查是在 HealthCheckOptions.Predicate 中傳回 false 來篩選出 StartupHostedServiceHealthCheck (如需詳細(xì)資訊,請參閱篩選健康情況檢查)

在下列範(fàn)例程式碼中:

整備檢查會使用具有「就緒」標(biāo)記的所有已登錄檢查。 Predicate 會排除所有檢查,並傳回 200-Ok。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions() { Predicate = (check) => check.Tags.Contains("ready"), }); endpoints.MapHealthChecks("/health/live", new HealthCheckOptions() { Predicate = (_) => false }); }

若要使用範(fàn)例應(yīng)用程式執(zhí)行整備度/活躍度組態(tài)案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario liveness

在瀏覽器中,瀏覽 /health/ready 數(shù)次,直到經(jīng)過 15 秒。 健康狀態(tài)檢查報告前 15 秒為 Unhealthy。 15 秒之後,端點(diǎn)會報告 Healthy,以反映託管服務(wù)長時間執(zhí)行的工作已完成。

此範(fàn)例也會建立一個以兩秒延遲執(zhí)行第一次整備檢查的「健康情況檢查發(fā)行者」(IHealthCheckPublisher 實(shí)作)。 如需詳細(xì)資訊,請參閱健康狀態(tài)檢查發(fā)行者一節(jié)。

Kubernetes 範(fàn)例

使用個別的整備度與活躍度檢查在 Kubernetes 之類的環(huán)境中很有用。 在 Kubernetes 中,應(yīng)用程式可能需要先執(zhí)行耗時的啟動工作,才能接受要求 (例如基礎(chǔ)資料庫可用性測試)。 使用個別的檢查可讓協(xié)調(diào)器區(qū)分應(yīng)用程式是否為正常運(yùn)作但尚未準(zhǔn)備好,或應(yīng)用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細(xì)資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設(shè)定活躍度與整備度探查)。

下列範(fàn)例示範(fàn) Kubernetes 整備度探查組態(tài):

spec: template: spec: readinessProbe: # an http probe httpGet: path: /health/ready port: 80 # length of time to wait for a pod to initialize # after pod startup, before applying health checking initialDelaySeconds: 30 timeoutSeconds: 1 ports: - containerPort: 80

透過自訂回應(yīng)寫入器的計量型探查

範(fàn)例應(yīng)用程式示範(fàn)透過自訂回應(yīng)寫入器的記憶體健康狀態(tài)檢查。

如果應(yīng)用程式使用超過指定的記憶體閾值 (在範(fàn)例應(yīng)用程式中為 1 GB),MemoryHealthCheck 會報告降級的狀態(tài)。 HealthCheckResult 包括應(yīng)用程式的記憶體回收行程 (GC) 資訊 (MemoryHealthCheck.cs):

public class MemoryHealthCheck : IHealthCheck { private readonly IOptionsMonitor<MemoryCheckOptions> _options; public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options) { _options = options; } public string Name => "memory_check"; public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { var options = _options.Get(context.Registration.Name); // Include GC information in the reported diagnostics. var allocated = GC.GetTotalMemory(forceFullCollection: false); var data = new Dictionary<string, object>() { { "AllocatedBytes", allocated }, { "Gen0Collections", GC.CollectionCount(0) }, { "Gen1Collections", GC.CollectionCount(1) }, { "Gen2Collections", GC.CollectionCount(2) }, }; var status = (allocated < options.Threshold) ? HealthStatus.Healthy : context.Registration.FailureStatus; return Task.FromResult(new HealthCheckResult( status, description: "Reports degraded status if allocated bytes " + $">= {options.Threshold} bytes.", exception: null, data: data)); } }

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 MemoryHealthCheck 會登錄為服務(wù),而不是將健康狀態(tài)檢查傳遞至 AddCheck 以啟用檢查。 所有 IHealthCheck 登錄的服務(wù)都可供健康狀態(tài)檢查服務(wù)和中介軟體使用。 建議將健康狀態(tài)檢查服務(wù)登錄為單一服務(wù)。

在範(fàn)例應(yīng)用程式的 CustomWriterStartup.cs 中:

services.AddHealthChecks() .AddMemoryHealthCheck("memory");

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks。 當(dāng)健康狀態(tài)檢查執(zhí)行時,會將 WriteResponse 委派提供給 ResponseWriter 屬性以輸出自訂 JSON 回應(yīng):

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { ResponseWriter = WriteResponse }); }

WriteResponse 委派會將 CompositeHealthCheckResult 格式化為 JSON 物件,並產(chǎn)生健康情況檢查回應(yīng)的 JSON 輸出。 如需詳細(xì)資訊,請參閱自訂輸出小節(jié)。

若要使用範(fàn)例應(yīng)用程式透過自訂回應(yīng)寫入器輸出執(zhí)行計量型探查,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario writer

依連接埠篩選

使用 URL 模式以在 MapHealthChecks 上呼叫 RequireHost,而此模式指定連接埠來限制針對所指定連接埠的健康情況檢查要求。 此方式通常用於容器環(huán)境,以公開監(jiān)控服務(wù)的連接埠。

範(fàn)例應(yīng)用程式使用環(huán)境變數(shù)組態(tài)提供者來設(shè)定連接埠。 連接埠是在 launchSettings.json 檔案中設(shè)定,並透過環(huán)境變數(shù)傳遞至設(shè)定提供者。 您也必須將伺服器設(shè)定為在管理連接埠上接聽要求。

若要使用範(fàn)例應(yīng)用程式來示範(fàn)管理連接埠設(shè)定,請在 Properties 資料夾中建立 launchSettings.json 檔案。

範(fàn)例應(yīng)用程式中的下列 Properties/launchSettings.json 檔案未包括在範(fàn)例應(yīng)用程式的專案檔中,而且必須手動予以建立:

{ "profiles": { "SampleApp": { "commandName": "Project", "commandLineArgs": "", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_URLS": "http://localhost:5000/;http://localhost:5001/", "ASPNETCORE_MANAGEMENTPORT": "5001" }, "applicationUrl": "http://localhost:5000/" } } }

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 在 Startup.Configure 中呼叫 MapHealthChecks,以建立健康情況檢查端點(diǎn)。

在範(fàn)例應(yīng)用程式中,對 Startup.Configure 中端點(diǎn)的 RequireHost 呼叫指定設(shè)定管理連接埠:

endpoints.MapHealthChecks("/health") .RequireHost($"*:{Configuration["ManagementPort"]}");

在範(fàn)例應(yīng)用程式的 Startup.Configure 中,建立端點(diǎn)。 在下列範(fàn)例程式碼中:

整備檢查會使用具有「就緒」標(biāo)記的所有已登錄檢查。 Predicate 會排除所有檢查,並傳回 200-Ok。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions() { Predicate = (check) => check.Tags.Contains("ready"), }); endpoints.MapHealthChecks("/health/live", new HealthCheckOptions() { Predicate = (_) => false }); }

注意

您可以在程式碼中明確設(shè)定管理連接埠,以避免在範(fàn)例應(yīng)用程式中建立 launchSettings.json 檔案。 在 HostBuilder 建立所在的 Program.cs 中,新增 ListenAnyIP 呼叫,並提供應(yīng)用程式的管理連接埠端點(diǎn)。 在 ManagementPortStartup.cs 的 Configure 中,使用 RequireHost 來指定管理連接埠:

Program.cs:

return new HostBuilder() .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseKestrel() .ConfigureKestrel(serverOptions => { serverOptions.ListenAnyIP(5001); }) .UseStartup(startupType); }) .Build();

ManagementPortStartup.cs:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health").RequireHost("*:5001"); });

若要使用範(fàn)例應(yīng)用程式執(zhí)行管理連接埠組態(tài)案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario port

發(fā)佈健康狀態(tài)檢查程式庫

若要發(fā)佈健康狀態(tài)檢查作為程式庫:

寫入健康狀態(tài)檢查,將 IHealthCheck 介面當(dāng)做獨(dú)立類別來實(shí)作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項(xiàng)來存取組態(tài)資料。

在 CheckHealthAsync 的健全狀況檢查邏輯中:

data1 和 data2 用於此方法,以執(zhí)行探查的健康情況檢查邏輯。 已處理 AccessViolationException。

發(fā)生 AccessViolationException 時,會使用 HealthCheckResult 來傳回 FailureStatus,以允許使用者設(shè)定健康情況檢查失敗狀態(tài)。

using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Diagnostics.HealthChecks; namespace SampleApp { public class ExampleHealthCheck : IHealthCheck { private readonly string _data1; private readonly int? _data2; public ExampleHealthCheck(string data1, int? data2) { _data1 = data1 ?? throw new ArgumentNullException(nameof(data1)); _data2 = data2 ?? throw new ArgumentNullException(nameof(data2)); } public async Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken) { try { return HealthCheckResult.Healthy(); } catch (AccessViolationException ex) { return new HealthCheckResult( context.Registration.FailureStatus, description: "An access violation occurred during the check.", exception: ex, data: null); } } } }

使用取用應(yīng)用程式在其 Startup.Configure 方法中呼叫的參數(shù),來寫入延伸模組。 在下列範(fàn)例中,假設(shè)健康狀態(tài)檢查方法簽章如下:

ExampleHealthCheck(string, string, int )

上述簽章指出 ExampleHealthCheck 需要額外的資料,才能處理健康狀態(tài)檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態(tài)檢查時,用來建立健康狀態(tài)檢查執(zhí)行個體。 在下列範(fàn)例中,呼叫者會選擇性地指定:

健康狀態(tài)檢查名稱 (name)。 如果為 null,則會使用 example_health_check。 健康狀態(tài)檢查的字串資料點(diǎn) (data1)。 健康狀態(tài)檢查的整數(shù)資料點(diǎn) (data2)。 如果為 null,則會使用 1。 失敗狀態(tài) (HealthStatus)。 預(yù)設(shè)值為 null。 如果為 null,則會報告失敗狀態(tài)為 HealthStatus.Unhealthy。 標(biāo)籤 (IEnumerable<string>)。

using System.Collections.Generic; using Microsoft.Extensions.Diagnostics.HealthChecks; public static class ExampleHealthCheckBuilderExtensions { const string DefaultName = "example_health_check"; public static IHealthChecksBuilder AddExampleHealthCheck( this IHealthChecksBuilder builder, string name = default, string data1, int data2 = 1, HealthStatus? failureStatus = default, IEnumerable<string> tags = default) { return builder.Add(new HealthCheckRegistration( name ?? DefaultName, sp => new ExampleHealthCheck(data1, data2), failureStatus, tags)); } }

健康狀態(tài)檢查發(fā)行者

當(dāng) IHealthCheckPublisher 新增至服務(wù)容器時,健康狀態(tài)檢查系統(tǒng)會定期執(zhí)行健康狀態(tài)檢查,並呼叫 PublishAsync 傳回結(jié)果。 這對推送型健康狀態(tài)監(jiān)控系統(tǒng)案例很有用,其預(yù)期每個處理序會定期呼叫監(jiān)控系統(tǒng)來判斷健康狀態(tài)。

IHealthCheckPublisher 介面有單一方法:

Task PublishAsync(HealthReport report, CancellationToken cancellationToken);

HealthCheckPublisherOptions 可讓您設(shè)定:

Delay:初始延遲會在應(yīng)用程式啟動之後且執(zhí)行 IHealthCheckPublisher 執(zhí)行個體之前套用。 在啟動後就會套用延遲,但不會套用至後續(xù)的反覆項(xiàng)目。 預(yù)設(shè)值是五秒鐘。 Period:IHealthCheckPublisher 執(zhí)行的期間。 預(yù)設(shè)值為 30 秒。 Predicate:如果 Predicate 為 null (預(yù)設(shè)),則健康情況檢查發(fā)行者服務(wù)會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行一部分的健康狀態(tài)檢查,請?zhí)峁┛珊Y選該組檢查的函式。 每個期間都會評估該述詞。 Timeout:執(zhí)行所有 IHealthCheckPublisher 執(zhí)行個體之健康情況檢查的逾時。 若要在沒有逾時的情況下執(zhí)行,請使用 InfiniteTimeSpan。 預(yù)設(shè)值為 30 秒。

在範(fàn)例應(yīng)用程式中,ReadinessPublisher 是一個 IHealthCheckPublisher 實(shí)作。 在下列記錄層級,會記錄每個檢查的健康情況檢查狀態(tài):

如果健康情況檢查狀態(tài)為 Healthy,則為資訊 (LogInformation)。 如果狀態(tài)為 Degraded 或 Unhealthy,則為錯誤 (LogError)。

public class ReadinessPublisher : IHealthCheckPublisher { private readonly ILogger _logger; public ReadinessPublisher(ILogger<ReadinessPublisher> logger) { _logger = logger; } // The following example is for demonstration purposes only. Health Checks // Middleware already logs health checks results. A real-world readiness // check in a production app might perform a set of more expensive or // time-consuming checks to determine if other resources are responding // properly. public Task PublishAsync(HealthReport report, CancellationToken cancellationToken) { if (report.Status == HealthStatus.Healthy) { _logger.LogInformation("{Timestamp} Readiness Probe Status: {Result}", DateTime.UtcNow, report.Status); } else { _logger.LogError("{Timestamp} Readiness Probe Status: {Result}", DateTime.UtcNow, report.Status); } cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } }

在範(fàn)例應(yīng)用程式的 LivenessProbeStartup 範(fàn)例中,StartupHostedService 整備檢查具有 2 秒的啟動延遲,且每 30 秒會執(zhí)行一次檢查。 為了啟用 IHealthCheckPublisher 實(shí)作,此範(fàn)例會在相依性插入 (DI) 容器中將 ReadinessPublisher 註冊為單一服務(wù):

services.AddHostedService<StartupHostedService>(); services.AddSingleton<StartupHostedServiceHealthCheck>(); services.AddHealthChecks() .AddCheck<StartupHostedServiceHealthCheck>( "hosted_service_startup", failureStatus: HealthStatus.Degraded, tags: new[] { "ready" }); services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(2); options.Predicate = (check) => check.Tags.Contains("ready"); }); services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

利用 MapWhen 限制健康情況檢查

使用 MapWhen 來有條件地將健康情況檢查端點(diǎn)的要求管線分支。

在下列範(fàn)例中,如果接收到 api/HealthCheck 端點(diǎn)的 GET 要求,則 MapWhen 會對要求管線進(jìn)行分支處理,以啟用健康情況檢查中介軟體:

app.MapWhen( context => context.Request.Method == HttpMethod.Get.Method && context.Request.Path.StartsWith("/api/HealthCheck"), builder => builder.UseHealthChecks()); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); });

如需詳細(xì)資訊,請參閱 ASP.NET Core 中介軟體。

ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應(yīng)用程式基礎(chǔ)結(jié)構(gòu)元件的健康情況。

應(yīng)用程式會將健康狀態(tài)檢查公開為 HTTP 端點(diǎn)。 您可以針對各種即時監(jiān)控案例來設(shè)定健康情況檢查端點(diǎn):

容器協(xié)調(diào)器和負(fù)載平衡器可以使用健康狀態(tài)探查,來檢查應(yīng)用程式的狀態(tài)。 例如,容器協(xié)調(diào)器可能會暫停輪流部署或重新啟動容器,來回應(yīng)失敗的健康狀態(tài)檢查。 負(fù)載平衡器可能會將流量從失敗的執(zhí)行個體路由傳送至狀況良好的執(zhí)行個體,來回應(yīng)狀況不良的應(yīng)用程式。 您可以監(jiān)控所使用記憶體、磁碟及其他實(shí)體伺服器資源的健康狀態(tài)。 健康狀態(tài)檢查可以測試應(yīng)用程式的相依性 (例如資料庫和外部服務(wù)端點(diǎn)),確認(rèn)其是否可用且正常運(yùn)作。

檢視或下載範(fàn)例程式碼 (英文) (如何下載)

範(fàn)例應(yīng)用程式包括本文中所述的案例範(fàn)例。 若要在指定的案例中執(zhí)行範(fàn)例應(yīng)用程式,請在命令殼層中使用來自專案資料夾的 dotnet run 命令。 如需如何使用範(fàn)例應(yīng)用程式的詳細(xì)資料,請參閱範(fàn)例應(yīng)用程式的 README.md 檔案和本文中的案例描述。

必要條件

健康情況檢查通常會與外部監(jiān)控服務(wù)或容器協(xié)調(diào)器搭配使用,來檢查應(yīng)用程式的狀態(tài)。 將健康狀態(tài)檢查新增至應(yīng)用程式之前,請決定要使用的監(jiān)控系統(tǒng)。 監(jiān)控系統(tǒng)會指定要建立哪些健康狀態(tài)檢查類型,以及如何設(shè)定其端點(diǎn)。

ASP.NET Core 應(yīng)用程式會隱含參考 Microsoft.AspNetCore.Diagnostics.HealthChecks 套件。 若要使用 Entity Framework Core 來執(zhí)行健康情況檢查,請新增 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore 套件的套件參考。

範(fàn)例應(yīng)用程式提供啟動程式碼,來示範(fàn)數(shù)個案例的健康狀態(tài)檢查。 資料庫探查案例使用 AspNetCore.Diagnostics.HealthChecks 來檢查資料庫連線的健康情況。 DbContext 探查案例使用 EF CoreDbContext 來檢查資料庫。 為了探索資料庫案例,範(fàn)例應(yīng)用程式會:

建立資料庫,並在 appsettings.json 檔案中提供其連接字串。 在其專案檔中具有下列套件參考: AspNetCore.HealthChecks.SqlServer Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore

另一個健康狀態(tài)檢查案例示範(fàn)如何將健康狀態(tài)檢查篩選至管理連接埠。 範(fàn)例應(yīng)用程式需要您建立 Properties/launchSettings.json 檔案,而此檔案包括管理 URL 和管理連接埠。 如需詳細(xì)資訊,請參閱依連接埠篩選一節(jié)。

基本健康狀態(tài)探查

對於許多應(yīng)用程式,報告應(yīng)用程式是否可處理要求的基本健康狀態(tài)探查組態(tài) (「活躍度」),便足以探索應(yīng)用程式的狀態(tài)。

基本設(shè)定會登錄健康情況檢查服務(wù),並呼叫健康情況檢查中介軟體以在具有健康情況回應(yīng)的 URL 端點(diǎn)做出回應(yīng)。 預(yù)設(shè)並未登錄特定健康狀態(tài)檢查來測試任何特定相依性或子系統(tǒng)。 如果應(yīng)用程式可以在健康情況端點(diǎn) URL 做出回應(yīng),則視為狀況良好。 預(yù)設(shè)回應(yīng)寫入器會將狀態(tài) (HealthStatus) 以純文字回應(yīng)形式回寫至用戶端,指出 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy 狀態(tài)。

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 在 Startup.Configure 中呼叫 MapHealthChecks,以建立健康情況檢查端點(diǎn)。

在範(fàn)例應(yīng)用程式中,是在 /health (BasicStartup.cs) 建立健康情況檢查端點(diǎn):

public class BasicStartup { public void ConfigureServices(IServiceCollection services) { services.AddHealthChecks(); } public void Configure(IApplicationBuilder app) { app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }); } }

若要使用範(fàn)例應(yīng)用程式執(zhí)行基本組態(tài)案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario basic

Docker 範(fàn)例

Docker 提供內(nèi)建 HEALTHCHECK 指示詞,可用來檢查使用基本健康狀態(tài)檢查組態(tài)的應(yīng)用程式狀態(tài):

HEALTHCHECK CMD curl --fail http://localhost:5000/health || exit

建立健康狀態(tài)檢查

健康狀態(tài)檢查是藉由實(shí)作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態(tài)為 Healthy、Degraded 或 Unhealthy 的 HealthCheckResult。 結(jié)果會寫成具有可設(shè)定狀態(tài)碼的純文字回應(yīng) (健康狀態(tài)檢查選項(xiàng)一節(jié)中將說明如何進(jìn)行組態(tài))。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。

下列 ExampleHealthCheck 類別示範(fàn)健康情況檢查的配置。 健康情況檢查邏輯放在 CheckHealthAsync 方法中。 下列範(fàn)例會將虛擬變數(shù) healthCheckResultHealthy 設(shè)定為 true。 如果 healthCheckResultHealthy 的值設(shè)定為 false,則會傳回 HealthCheckResult.Unhealthy 狀態(tài)。

public class ExampleHealthCheck : IHealthCheck { public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { var healthCheckResultHealthy = true; if (healthCheckResultHealthy) { return Task.FromResult( HealthCheckResult.Healthy("A healthy result.")); } return Task.FromResult( HealthCheckResult.Unhealthy("An unhealthy result.")); } }

登錄健康狀態(tài)檢查服務(wù)

在 Startup.ConfigureServices 中使用 AddCheck,以將 ExampleHealthCheck 類型新增至健康情況檢查服務(wù):

services.AddHealthChecks() .AddCheck<ExampleHealthCheck>("example_health_check");

下列範(fàn)例中所顯示的 AddCheck 多載會設(shè)定在健康狀態(tài)檢查報告失敗時所要報告的失敗狀態(tài) (HealthStatus)。 如果將失敗狀態(tài)設(shè)定為 null (預(yù)設(shè)),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態(tài)檢查實(shí)作採用此設(shè)定,則當(dāng)健康狀態(tài)檢查失敗時,應(yīng)用程式就會強(qiáng)制程式庫指出失敗狀態(tài)。

您可以使用「標(biāo)籤」來篩選健康狀態(tài)檢查 (篩選健康狀態(tài)檢查一節(jié)中將進(jìn)一步說明)。

services.AddHealthChecks() .AddCheck<ExampleHealthCheck>( "example_health_check", failureStatus: HealthStatus.Degraded, tags: new[] { "example" });

AddCheck 也可以執(zhí)行匿名函式。 在下列範(fàn)例中,健康狀態(tài)檢查名稱指定為 Example,且檢查一律會傳回狀況良好狀態(tài):

services.AddHealthChecks() .AddCheck("Example", () => HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });

呼叫 AddTypeActivatedCheck,以將引數(shù)傳遞至健康情況檢查實(shí)作。 在下列範(fàn)例中,TestHealthCheckWithArgs 接受在呼叫 CheckHealthAsync 時使用整數(shù)和字串:

private class TestHealthCheckWithArgs : IHealthCheck { public TestHealthCheckWithArgs(int i, string s) { I = i; S = s; } public int I { get; set; } public string S { get; set; } public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) { ... } }

使用傳遞至實(shí)作的整數(shù)和字串來呼叫 AddTypeActivatedCheck,以登錄 TestHealthCheckWithArgs:

services.AddHealthChecks() .AddTypeActivatedCheck<TestHealthCheckWithArgs>( "test", failureStatus: HealthStatus.Degraded, tags: new[] { "example" }, args: new object[] { 5, "string" });

使用健康情況檢查路由傳送

在 Startup.Configure 中,使用端點(diǎn) URL 或相對路徑以在端點(diǎn)建立器上呼叫 MapHealthChecks:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); });

需要主機(jī)

呼叫 RequireHost,以將一或多個允許的主機(jī)指定給健康情況檢查端點(diǎn)。 主機(jī)應(yīng)該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機(jī)。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001"); });

如需詳細(xì)資訊,請參閱依連接埠篩選一節(jié)。

需要授權(quán)

呼叫 RequireAuthorization,以在健康情況檢查要求端點(diǎn)上執(zhí)行授權(quán)中介軟體。 RequireAuthorization 多載接受一或多個授權(quán)原則。 如果未提供原則,則會使用預(yù)設(shè)授權(quán)原則。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health").RequireAuthorization(); });

啟用跨原始來源要求 (CORS)

雖然從瀏覽器手動執(zhí)行健康情況檢查不是常見使用案例,但是您可以在健康情況檢查端點(diǎn)上呼叫 RequireCors,以啟用 CORS 中介軟體。 RequireCors 多載接受 CORS 原則建立器委派 (CorsPolicyBuilder) 或原則名稱。 如果未提供原則,則會使用預(yù)設(shè) CORS 原則。 如需詳細(xì)資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。

健康狀態(tài)檢查選項(xiàng)

HealthCheckOptions 讓您有機(jī)會自訂健康狀態(tài)檢查行為:

篩選健康狀態(tài)檢查 自訂 HTTP 狀態(tài)碼 隱藏快取標(biāo)頭 自訂輸出

篩選健康狀態(tài)檢查

根據(jù)預(yù)設(shè),健康情況檢查中介軟體會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行健康狀態(tài)檢查子集,請對 Predicate 選項(xiàng)提供傳回布林值的函式。 在下列範(fàn)例中,會依函式條件陳述式中的標(biāo)籤 (bar_tag) 篩選出 Bar 健康狀態(tài)檢查。只有在健康狀態(tài)檢查的 Tags 屬性符合 foo_tag 或 baz_tag 時,才傳回 true:

在 Startup.ConfigureServices 中:

services.AddHealthChecks() .AddCheck("Foo", () => HealthCheckResult.Healthy("Foo is OK!"), tags: new[] { "foo_tag" }) .AddCheck("Bar", () => HealthCheckResult.Unhealthy("Bar is unhealthy!"), tags: new[] { "bar_tag" }) .AddCheck("Baz", () => HealthCheckResult.Healthy("Baz is OK!"), tags: new[] { "baz_tag" });

在 Startup.Configure 中,Predicate 會篩選出「橫條圖」健康情況檢查。 只有 Foo 和 Baz 才能執(zhí)行:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { Predicate = (check) => check.Tags.Contains("foo_tag") || check.Tags.Contains("baz_tag") }); });

自訂 HTTP 狀態(tài)碼

您可以使用 ResultStatusCodes 來自訂健康狀態(tài)與 HTTP 狀態(tài)碼的對應(yīng)。 下列 StatusCodes 指派是中介軟體所使用的預(yù)設(shè)值。 請變更狀態(tài)碼值以符合您的需求。

在 Startup.Configure 中:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { ResultStatusCodes = { [HealthStatus.Healthy] = StatusCodes.Status200OK, [HealthStatus.Degraded] = StatusCodes.Status200OK, [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable } }); });

隱藏快取標(biāo)頭

AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標(biāo)頭新增至探查回應(yīng),以防止回應(yīng)快取。 如果值為 false (預(yù)設(shè)),則中介軟體會設(shè)定或覆寫 Cache-Control、Expires 和 Pragma 標(biāo)頭,以防止回應(yīng)快取。 如果值為 true,則中介軟體不會修改回應(yīng)的快取標(biāo)頭。

在 Startup.Configure 中:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { AllowCachingResponses = true }); });

自訂輸出

在 Startup.Configure 中,將 HealthCheckOptions.ResponseWriter 選項(xiàng)設(shè)定為撰寫回應(yīng)的委派:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { ResponseWriter = WriteResponse }); });

預(yù)設(shè)委派會使用字串值 HealthReport.Status 寫入基本純文字回應(yīng)。 下列自訂委派會輸出自訂 JSON 回應(yīng)。

範(fàn)例應(yīng)用程式中的第一個範(fàn)例示範(fàn)如何使用 System.Text.Json:

private static Task WriteResponse(HttpContext context, HealthReport result) { context.Response.ContentType = "application/json; charset=utf-8"; var options = new JsonWriterOptions { Indented = true }; using (var stream = new MemoryStream()) { using (var writer = new Utf8JsonWriter(stream, options)) { writer.WriteStartObject(); writer.WriteString("status", result.Status.ToString()); writer.WriteStartObject("results"); foreach (var entry in result.Entries) { writer.WriteStartObject(entry.Key); writer.WriteString("status", entry.Value.Status.ToString()); writer.WriteString("description", entry.Value.Description); writer.WriteStartObject("data"); foreach (var item in entry.Value.Data) { writer.WritePropertyName(item.Key); JsonSerializer.Serialize( writer, item.Value, item.Value?.GetType() ?? typeof(object)); } writer.WriteEndObject(); writer.WriteEndObject(); } writer.WriteEndObject(); writer.WriteEndObject(); } var json = Encoding.UTF8.GetString(stream.ToArray()); return context.Response.WriteAsync(json); } }

第二個範(fàn)例示範(fàn)如何使用 Newtonsoft.Json:

private static Task WriteResponse(HttpContext context, HealthReport result) { context.Response.ContentType = "application/json"; var json = new JObject( new JProperty("status", result.Status.ToString()), new JProperty("results", new JObject(result.Entries.Select(pair => new JProperty(pair.Key, new JObject( new JProperty("status", pair.Value.Status.ToString()), new JProperty("description", pair.Value.Description), new JProperty("data", new JObject(pair.Value.Data.Select( p => new JProperty(p.Key, p.Value)))))))))); return context.Response.WriteAsync( json.ToString(Formatting.Indented)); }

在範(fàn)例應(yīng)用程式中,註解化 CustomWriterStartup.cs 中的 SYSTEM_TEXT_JSON 前置處理器指示詞,以啟用 WriteResponse 的 Newtonsoft.Json 版本。

健康情況檢查 API 未提供複雜 JSON 傳回格式的內(nèi)建支援,因?yàn)榇烁袷绞悄x擇的監(jiān)控系統(tǒng)所特有。 視需要,自訂上述範(fàn)例中的回應(yīng)。 如需使用 System.Text.Json進(jìn)行 JSON 序列化的詳細(xì)資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。

資料庫探查

健康狀態(tài)檢查可指定資料庫查詢以布林測試方式來執(zhí)行,藉此指出資料庫是否正?;貞?yīng)。

範(fàn)例應(yīng)用程式使用 AspNetCore.Diagnostics.HealthChecks (一種適用於 ASP.NET Core 應(yīng)用程式的健康情況檢查程式庫),以在 SQL Server 資料庫上執(zhí)行健康情況檢查。 AspNetCore.Diagnostics.HealthChecks 會對資料庫執(zhí)行 SELECT 1 查詢,以確認(rèn)資料庫連線狀況良好。

警告

使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風(fēng)險。 在大部分情況下,不需要執(zhí)行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發(fā)現(xiàn)有必要執(zhí)行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1。

包括 AspNetCore.HealthChecks.SqlServer 的套件參考。

在範(fàn)例應(yīng)用程式的 appsettings.json 檔案中,提供有效的資料庫連接字串。 應(yīng)用程式使用名為 HealthCheckSample 的 SQL Server 資料庫:

{ "ConnectionStrings": { "DefaultConnection": "Server=(localdb)\MSSQLLocalDB;Database=HealthCheckSample;Trusted_Connection=True;MultipleActiveResultSets=true;ConnectRetryCount=0" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" }, "Console": { "IncludeScopes": "true" } }, "AllowedHosts": "*" }

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 範(fàn)例應(yīng)用程式會使用資料庫連接字串 (DbHealthStartup.cs) 來呼叫 AddSqlServer 方法:

services.AddHealthChecks() .AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }

若要使用範(fàn)例應(yīng)用程式執(zhí)行資料庫探查案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario db

Entity Framework Core DbContext 探查

DbContext 檢查會確認(rèn)應(yīng)用程式是否可以與針對 EF CoreDbContext 所設(shè)定的資料庫通訊。 應(yīng)用程式支援 DbContext 檢查:

使用 Entity Framework (EF) Core。 包括 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore 的套件參考。

AddDbContextCheck<TContext> 會登錄 DbContext 的健康狀態(tài)檢查。 DbContext 會以 TContext 形式提供給方法。 多載可用來設(shè)定失敗狀態(tài)、標(biāo)籤和自訂測試查詢。

預(yù)設(shè)情況:

DbContextHealthCheck 會呼叫 EF Core 的 CanConnectAsync 方法。 您可以自訂使用 AddDbContextCheck 方法多載檢查健康狀態(tài)時所要執(zhí)行的作業(yè)。 健康狀態(tài)檢查的名稱是 TContext 類型的名稱。

在範(fàn)例應(yīng)用程式中,會將 AppDbContext 提供給 AddDbContextCheck,並在 Startup.ConfigureServices 中登錄為服務(wù) (DbContextHealthStartup.cs):

services.AddHealthChecks() .AddDbContextCheck<AppDbContext>(); services.AddDbContext<AppDbContext>(options => { options.UseSqlServer( Configuration["ConnectionStrings:DefaultConnection"]); });

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health"); }

若要使用範(fàn)例應(yīng)用程式來執(zhí)行 DbContext 探查案例,請確認(rèn) SQL Server 執(zhí)行個體中沒有連接字串所指定的資料庫。 如果資料庫存在,請予以刪除。

在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario dbcontext

在應(yīng)用程式執(zhí)行之後,對瀏覽器中的 /health 端點(diǎn)提出要求來檢查健康狀態(tài)。 資料庫和 AppDbContext 不存在,因此應(yīng)用程式會提供下列回應(yīng):

Unhealthy

觸發(fā)範(fàn)例應(yīng)用程式以建立資料庫。 對 /createdatabase 提出要求。 應(yīng)用程式會回應(yīng):

Creating the database... Done! Navigate to /health to see the health status.

對 /health 端點(diǎn)提出要求。 資料庫和內(nèi)容存在,因此應(yīng)用程式會回應(yīng):

Healthy

觸發(fā)範(fàn)例應(yīng)用程式以刪除資料庫。 對 /deletedatabase 提出要求。 應(yīng)用程式會回應(yīng):

Deleting the database... Done! Navigate to /health to see the health status.

對 /health 端點(diǎn)提出要求。 應(yīng)用程式會提供狀況不良回應(yīng):

Unhealthy

個別的整備度與活躍度探查

在某些裝載案例中,會使用一組健康情況檢查來區(qū)分兩個應(yīng)用程式狀態(tài):

「整備」指出應(yīng)用程式是否正在正常執(zhí)行,但尚未準(zhǔn)備好接收要求。 「活躍度」指出應(yīng)用程式是否已當(dāng)機(jī),而且必須重新予以啟動。

請考慮下列範(fàn)例:應(yīng)用程式在準(zhǔn)備好處理要求之前必須下載大型設(shè)定檔。 如果初始下載失敗,則我們不想要重新啟動應(yīng)用程式,因?yàn)閼?yīng)用程式可以重試下載檔案數(shù)次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執(zhí)行其他檢查。 我們也想要防止在設(shè)定檔下載成功之前將要求傳送至應(yīng)用程式。 除非下載成功,而且應(yīng)用程式準(zhǔn)備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」?fàn)顟B(tài)。

範(fàn)例應(yīng)用程式包含健康狀態(tài)檢查,會在託管服務(wù)中長時間執(zhí)行的啟動工作完成時回報。 StartupHostedServiceHealthCheck 會公開 StartupTaskCompleted 屬性,而裝載的服務(wù)可以在其長時間執(zhí)行的工作完成時,將此屬性設(shè)定為 true (StartupHostedServiceHealthCheck.cs):

public class StartupHostedServiceHealthCheck : IHealthCheck { private volatile bool _startupTaskCompleted = false; public string Name => "slow_dependency_check"; public bool StartupTaskCompleted { get => _startupTaskCompleted; set => _startupTaskCompleted = value; } public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { if (StartupTaskCompleted) { return Task.FromResult( HealthCheckResult.Healthy("The startup task is finished.")); } return Task.FromResult( HealthCheckResult.Unhealthy("The startup task is still running.")); } }

裝載的服務(wù) (Services/StartupHostedService) 會啟動長時間執(zhí)行的背景工作。 工作完成時,StartupHostedServiceHealthCheck.StartupTaskCompleted 會設(shè)定為 true:

public class StartupHostedService : IHostedService, IDisposable { private readonly int _delaySeconds = 15; private readonly ILogger _logger; private readonly StartupHostedServiceHealthCheck _startupHostedServiceHealthCheck; public StartupHostedService(ILogger<StartupHostedService> logger, StartupHostedServiceHealthCheck startupHostedServiceHealthCheck) { _logger = logger; _startupHostedServiceHealthCheck = startupHostedServiceHealthCheck; } public Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("Startup Background Service is starting."); // Simulate the effect of a long-running startup task. Task.Run(async () => { await Task.Delay(_delaySeconds * 1000); _startupHostedServiceHealthCheck.StartupTaskCompleted = true; _logger.LogInformation("Startup Background Service has started."); }); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("Startup Background Service is stopping."); return Task.CompletedTask; } public void Dispose() { } }

健康狀態(tài)檢查是 Startup.ConfigureServices 中使用 AddCheck 隨託管服務(wù)一起登錄。 因?yàn)樗b載服務(wù)必須在健康情況檢查上設(shè)定此屬性,所以也會在服務(wù)容器中登錄健康情況檢查 (LivenessProbeStartup.cs):

services.AddHostedService<StartupHostedService>(); services.AddSingleton<StartupHostedServiceHealthCheck>(); services.AddHealthChecks() .AddCheck<StartupHostedServiceHealthCheck>( "hosted_service_startup", failureStatus: HealthStatus.Degraded, tags: new[] { "ready" }); services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(2); options.Predicate = (check) => check.Tags.Contains("ready"); }); services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks。 在範(fàn)例應(yīng)用程式中,是在下列位置建立健康情況檢查端點(diǎn):

/health/ready 用於整備檢查。 整備度檢查使用 ready 標(biāo)籤來篩選健康狀態(tài)檢查。 /health/live 用於活躍度檢查。 活躍度檢查是在 HealthCheckOptions.Predicate 中傳回 false 來篩選出 StartupHostedServiceHealthCheck (如需詳細(xì)資訊,請參閱篩選健康情況檢查)

在下列範(fàn)例程式碼中:

整備檢查會使用具有「就緒」標(biāo)記的所有已登錄檢查。 Predicate 會排除所有檢查,並傳回 200-Ok。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions() { Predicate = (check) => check.Tags.Contains("ready"), }); endpoints.MapHealthChecks("/health/live", new HealthCheckOptions() { Predicate = (_) => false }); }

若要使用範(fàn)例應(yīng)用程式執(zhí)行整備度/活躍度組態(tài)案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario liveness

在瀏覽器中,瀏覽 /health/ready 數(shù)次,直到經(jīng)過 15 秒。 健康狀態(tài)檢查報告前 15 秒為 Unhealthy。 15 秒之後,端點(diǎn)會報告 Healthy,以反映託管服務(wù)長時間執(zhí)行的工作已完成。

此範(fàn)例也會建立一個以兩秒延遲執(zhí)行第一次整備檢查的「健康情況檢查發(fā)行者」(IHealthCheckPublisher 實(shí)作)。 如需詳細(xì)資訊,請參閱健康狀態(tài)檢查發(fā)行者一節(jié)。

Kubernetes 範(fàn)例

使用個別的整備度與活躍度檢查在 Kubernetes 之類的環(huán)境中很有用。 在 Kubernetes 中,應(yīng)用程式可能需要先執(zhí)行耗時的啟動工作,才能接受要求 (例如基礎(chǔ)資料庫可用性測試)。 使用個別的檢查可讓協(xié)調(diào)器區(qū)分應(yīng)用程式是否為正常運(yùn)作但尚未準(zhǔn)備好,或應(yīng)用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細(xì)資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設(shè)定活躍度與整備度探查)。

下列範(fàn)例示範(fàn) Kubernetes 整備度探查組態(tài):

spec: template: spec: readinessProbe: # an http probe httpGet: path: /health/ready port: 80 # length of time to wait for a pod to initialize # after pod startup, before applying health checking initialDelaySeconds: 30 timeoutSeconds: 1 ports: - containerPort: 80

透過自訂回應(yīng)寫入器的計量型探查

範(fàn)例應(yīng)用程式示範(fàn)透過自訂回應(yīng)寫入器的記憶體健康狀態(tài)檢查。

如果應(yīng)用程式使用超過指定的記憶體閾值 (在範(fàn)例應(yīng)用程式中為 1 GB),MemoryHealthCheck 會報告降級的狀態(tài)。 HealthCheckResult 包括應(yīng)用程式的記憶體回收行程 (GC) 資訊 (MemoryHealthCheck.cs):

public class MemoryHealthCheck : IHealthCheck { private readonly IOptionsMonitor<MemoryCheckOptions> _options; public MemoryHealthCheck(IOptionsMonitor<MemoryCheckOptions> options) { _options = options; } public string Name => "memory_check"; public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { var options = _options.Get(context.Registration.Name); // Include GC information in the reported diagnostics. var allocated = GC.GetTotalMemory(forceFullCollection: false); var data = new Dictionary<string, object>() { { "AllocatedBytes", allocated }, { "Gen0Collections", GC.CollectionCount(0) }, { "Gen1Collections", GC.CollectionCount(1) }, { "Gen2Collections", GC.CollectionCount(2) }, }; var status = (allocated < options.Threshold) ? HealthStatus.Healthy : context.Registration.FailureStatus; return Task.FromResult(new HealthCheckResult( status, description: "Reports degraded status if allocated bytes " + $">= {options.Threshold} bytes.", exception: null, data: data)); } }

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 MemoryHealthCheck 會登錄為服務(wù),而不是將健康狀態(tài)檢查傳遞至 AddCheck 以啟用檢查。 所有 IHealthCheck 登錄的服務(wù)都可供健康狀態(tài)檢查服務(wù)和中介軟體使用。 建議將健康狀態(tài)檢查服務(wù)登錄為單一服務(wù)。

在範(fàn)例應(yīng)用程式的 CustomWriterStartup.cs 中:

services.AddHealthChecks() .AddMemoryHealthCheck("memory");

健康情況檢查端點(diǎn)的建立方式是在 Startup.Configure 中呼叫 MapHealthChecks。 當(dāng)健康狀態(tài)檢查執(zhí)行時,會將 WriteResponse 委派提供給 ResponseWriter 屬性以輸出自訂 JSON 回應(yīng):

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health", new HealthCheckOptions() { ResponseWriter = WriteResponse }); }

WriteResponse 委派會將 CompositeHealthCheckResult 格式化為 JSON 物件,並產(chǎn)生健康情況檢查回應(yīng)的 JSON 輸出。 如需詳細(xì)資訊,請參閱自訂輸出小節(jié)。

若要使用範(fàn)例應(yīng)用程式透過自訂回應(yīng)寫入器輸出執(zhí)行計量型探查,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario writer

依連接埠篩選

使用 URL 模式以在 MapHealthChecks 上呼叫 RequireHost,而此模式指定連接埠來限制針對所指定連接埠的健康情況檢查要求。 此方式通常用於容器環(huán)境,以公開監(jiān)控服務(wù)的連接埠。

範(fàn)例應(yīng)用程式使用環(huán)境變數(shù)組態(tài)提供者來設(shè)定連接埠。 連接埠是在 launchSettings.json 檔案中設(shè)定,並透過環(huán)境變數(shù)傳遞至設(shè)定提供者。 您也必須將伺服器設(shè)定為在管理連接埠上接聽要求。

若要使用範(fàn)例應(yīng)用程式來示範(fàn)管理連接埠設(shè)定,請在 Properties 資料夾中建立 launchSettings.json 檔案。

範(fàn)例應(yīng)用程式中的下列 Properties/launchSettings.json 檔案未包括在範(fàn)例應(yīng)用程式的專案檔中,而且必須手動予以建立:

{ "profiles": { "SampleApp": { "commandName": "Project", "commandLineArgs": "", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_URLS": "http://localhost:5000/;http://localhost:5001/", "ASPNETCORE_MANAGEMENTPORT": "5001" }, "applicationUrl": "http://localhost:5000/" } } }

在 Startup.ConfigureServices 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 在 Startup.Configure 中呼叫 MapHealthChecks,以建立健康情況檢查端點(diǎn)。

在範(fàn)例應(yīng)用程式中,對 Startup.Configure 中端點(diǎn)的 RequireHost 呼叫指定設(shè)定管理連接埠:

endpoints.MapHealthChecks("/health") .RequireHost($"*:{Configuration["ManagementPort"]}");

在範(fàn)例應(yīng)用程式的 Startup.Configure 中,建立端點(diǎn)。 在下列範(fàn)例程式碼中:

整備檢查會使用具有「就緒」標(biāo)記的所有已登錄檢查。 Predicate 會排除所有檢查,並傳回 200-Ok。

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions() { Predicate = (check) => check.Tags.Contains("ready"), }); endpoints.MapHealthChecks("/health/live", new HealthCheckOptions() { Predicate = (_) => false }); }

注意

您可以在程式碼中明確設(shè)定管理連接埠,以避免在範(fàn)例應(yīng)用程式中建立 launchSettings.json 檔案。 在 HostBuilder 建立所在的 Program.cs 中,新增 ListenAnyIP 呼叫,並提供應(yīng)用程式的管理連接埠端點(diǎn)。 在 ManagementPortStartup.cs 的 Configure 中,使用 RequireHost 來指定管理連接埠:

Program.cs:

return new HostBuilder() .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseKestrel() .ConfigureKestrel(serverOptions => { serverOptions.ListenAnyIP(5001); }) .UseStartup(startupType); }) .Build();

ManagementPortStartup.cs:

app.UseEndpoints(endpoints => { endpoints.MapHealthChecks("/health").RequireHost("*:5001"); });

若要使用範(fàn)例應(yīng)用程式執(zhí)行管理連接埠組態(tài)案例,請在命令殼層中執(zhí)行來自專案資料夾的下列命令:

dotnet run --scenario port

發(fā)佈健康狀態(tài)檢查程式庫

若要發(fā)佈健康狀態(tài)檢查作為程式庫:

寫入健康狀態(tài)檢查,將 IHealthCheck 介面當(dāng)做獨(dú)立類別來實(shí)作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項(xiàng)來存取組態(tài)資料。

在 CheckHealthAsync 的健全狀況檢查邏輯中:

data1 和 data2 用於此方法,以執(zhí)行探查的健康情況檢查邏輯。 已處理 AccessViolationException。

發(fā)生 AccessViolationException 時,會使用 HealthCheckResult 來傳回 FailureStatus,以允許使用者設(shè)定健康情況檢查失敗狀態(tài)。

using System; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Diagnostics.HealthChecks; namespace SampleApp { public class ExampleHealthCheck : IHealthCheck { private readonly string _data1; private readonly int? _data2; public ExampleHealthCheck(string data1, int? data2) { _data1 = data1 ?? throw new ArgumentNullException(nameof(data1)); _data2 = data2 ?? throw new ArgumentNullException(nameof(data2)); } public async Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken) { try { return HealthCheckResult.Healthy(); } catch (AccessViolationException ex) { return new HealthCheckResult( context.Registration.FailureStatus, description: "An access violation occurred during the check.", exception: ex, data: null); } } } }

使用取用應(yīng)用程式在其 Startup.Configure 方法中呼叫的參數(shù),來寫入延伸模組。 在下列範(fàn)例中,假設(shè)健康狀態(tài)檢查方法簽章如下:

ExampleHealthCheck(string, string, int )

上述簽章指出 ExampleHealthCheck 需要額外的資料,才能處理健康狀態(tài)檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態(tài)檢查時,用來建立健康狀態(tài)檢查執(zhí)行個體。 在下列範(fàn)例中,呼叫者會選擇性地指定:

健康狀態(tài)檢查名稱 (name)。 如果為 null,則會使用 example_health_check。 健康狀態(tài)檢查的字串資料點(diǎn) (data1)。 健康狀態(tài)檢查的整數(shù)資料點(diǎn) (data2)。 如果為 null,則會使用 1。 失敗狀態(tài) (HealthStatus)。 預(yù)設(shè)值為 null。 如果為 null,則會報告失敗狀態(tài)為 HealthStatus.Unhealthy。 標(biāo)籤 (IEnumerable<string>)。

using System.Collections.Generic; using Microsoft.Extensions.Diagnostics.HealthChecks; public static class ExampleHealthCheckBuilderExtensions { const string DefaultName = "example_health_check"; public static IHealthChecksBuilder AddExampleHealthCheck( this IHealthChecksBuilder builder, string name = default, string data1, int data2 = 1, HealthStatus? failureStatus = default, IEnumerable<string> tags = default) { return builder.Add(new HealthCheckRegistration( name ?? DefaultName, sp => new ExampleHealthCheck(data1, data2), failureStatus, tags)); } }

健康狀態(tài)檢查發(fā)行者

當(dāng) IHealthCheckPublisher 新增至服務(wù)容器時,健康狀態(tài)檢查系統(tǒng)會定期執(zhí)行健康狀態(tài)檢查,並呼叫 PublishAsync 傳回結(jié)果。 這對推送型健康狀態(tài)監(jiān)控系統(tǒng)案例很有用,其預(yù)期每個處理序會定期呼叫監(jiān)控系統(tǒng)來判斷健康狀態(tài)。

IHealthCheckPublisher 介面有單一方法:

Task PublishAsync(HealthReport report, CancellationToken cancellationToken);

HealthCheckPublisherOptions 可讓您設(shè)定:

Delay:初始延遲會在應(yīng)用程式啟動之後且執(zhí)行 IHealthCheckPublisher 執(zhí)行個體之前套用。 在啟動後就會套用延遲,但不會套用至後續(xù)的反覆項(xiàng)目。 預(yù)設(shè)值是五秒鐘。 Period:IHealthCheckPublisher 執(zhí)行的期間。 預(yù)設(shè)值為 30 秒。 Predicate:如果 Predicate 為 null (預(yù)設(shè)),則健康情況檢查發(fā)行者服務(wù)會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行一部分的健康狀態(tài)檢查,請?zhí)峁┛珊Y選該組檢查的函式。 每個期間都會評估該述詞。 Timeout:執(zhí)行所有 IHealthCheckPublisher 執(zhí)行個體之健康情況檢查的逾時。 若要在沒有逾時的情況下執(zhí)行,請使用 InfiniteTimeSpan。 預(yù)設(shè)值為 30 秒。

在範(fàn)例應(yīng)用程式中,ReadinessPublisher 是一個 IHealthCheckPublisher 實(shí)作。 在下列記錄層級,會記錄每個檢查的健康情況檢查狀態(tài):

如果健康情況檢查狀態(tài)為 Healthy,則為資訊 (LogInformation)。 如果狀態(tài)為 Degraded 或 Unhealthy,則為錯誤 (LogError)。

public class ReadinessPublisher : IHealthCheckPublisher { private readonly ILogger _logger; public ReadinessPublisher(ILogger<ReadinessPublisher> logger) { _logger = logger; } // The following example is for demonstration purposes only. Health Checks // Middleware already logs health checks results. A real-world readiness // check in a production app might perform a set of more expensive or // time-consuming checks to determine if other resources are responding // properly. public Task PublishAsync(HealthReport report, CancellationToken cancellationToken) { if (report.Status == HealthStatus.Healthy) { _logger.LogInformation("{Timestamp} Readiness Probe Status: {Result}", DateTime.UtcNow, report.Status); } else { _logger.LogError("{Timestamp} Readiness Probe Status: {Result}", DateTime.UtcNow, report.Status); } cancellationToken.ThrowIfCancellationRequested(); return Task.CompletedTask; } }

在範(fàn)例應(yīng)用程式的 LivenessProbeStartup 範(fàn)例中,StartupHostedService 整備檢查具有 2 秒的啟動延遲,且每 30 秒會執(zhí)行一次檢查。 為了啟用 IHealthCheckPublisher 實(shí)作,此範(fàn)例會在相依性插入 (DI) 容器中將 ReadinessPublisher 註冊為單一服務(wù):

services.AddHostedService<StartupHostedService>(); services.AddSingleton<StartupHostedServiceHealthCheck>(); services.AddHealthChecks() .AddCheck<StartupHostedServiceHealthCheck>( "hosted_service_startup", failureStatus: HealthStatus.Degraded, tags: new[] { "ready" }); services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(2); options.Predicate = (check) => check.Tags.Contains("ready"); }); services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();

利用 MapWhen 限制健康情況檢查

使用 MapWhen 來有條件地將健康情況檢查端點(diǎn)的要求管線分支。

在下列範(fàn)例中,如果接收到 api/HealthCheck 端點(diǎn)的 GET 要求,則 MapWhen 會對要求管線進(jìn)行分支處理,以啟用健康情況檢查中介軟體:

app.MapWhen( context => context.Request.Method == HttpMethod.Get.Method && context.Request.Path.StartsWith("/api/HealthCheck"), builder => builder.UseHealthChecks()); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); });

如需詳細(xì)資訊,請參閱 ASP.NET Core 中介軟體。

ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應(yīng)用程式基礎(chǔ)結(jié)構(gòu)元件的健康情況。

應(yīng)用程式會將健康狀態(tài)檢查公開為 HTTP 端點(diǎn)。 您可以針對各種即時監(jiān)控案例來設(shè)定健康情況檢查端點(diǎn):

容器協(xié)調(diào)器和負(fù)載平衡器可以使用健康狀態(tài)探查,來檢查應(yīng)用程式的狀態(tài)。 例如,容器協(xié)調(diào)器可能會暫停輪流部署或重新啟動容器,來回應(yīng)失敗的健康狀態(tài)檢查。 負(fù)載平衡器可能會將流量從失敗的執(zhí)行個體路由傳送至狀況良好的執(zhí)行個體,來回應(yīng)狀況不良的應(yīng)用程式。 您可以監(jiān)控所使用記憶體、磁碟及其他實(shí)體伺服器資源的健康狀態(tài)。 健康狀態(tài)檢查可以測試應(yīng)用程式的相依性 (例如資料庫和外部服務(wù)端點(diǎn)),確認(rèn)其是否可用且正常運(yùn)作。

健康情況檢查通常會與外部監(jiān)控服務(wù)或容器協(xié)調(diào)器搭配使用,來檢查應(yīng)用程式的狀態(tài)。 將健康狀態(tài)檢查新增至應(yīng)用程式之前,請決定要使用的監(jiān)控系統(tǒng)。 監(jiān)控系統(tǒng)會指定要建立哪些健康狀態(tài)檢查類型,以及如何設(shè)定其端點(diǎn)。

基本健康狀態(tài)探查

對於許多應(yīng)用程式,報告應(yīng)用程式是否可處理要求的基本健康狀態(tài)探查組態(tài) (「活躍度」),便足以探索應(yīng)用程式的狀態(tài)。

基本設(shè)定會登錄健康情況檢查服務(wù),並呼叫健康情況檢查中介軟體以在具有健康情況回應(yīng)的 URL 端點(diǎn)做出回應(yīng)。 預(yù)設(shè)並未登錄特定健康狀態(tài)檢查來測試任何特定相依性或子系統(tǒng)。 如果應(yīng)用程式可以在健康情況端點(diǎn) URL 做出回應(yīng),則視為狀況良好。 預(yù)設(shè)回應(yīng)寫入器會將 HealthStatus 以純文字回應(yīng)形式寫入至用戶端。 HealthStatus 是 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy。

在 Program.cs 中,使用 AddHealthChecks 登錄健康狀態(tài)檢查服務(wù)。 呼叫 MapHealthChecks 來建立健康情況檢查端點(diǎn)。

下列範(fàn)例會在 /healthz 建立健康情況檢查端點(diǎn):

var builder = WebApplication.CreateBuilder(args); builder.Services.AddHealthChecks(); var app = builder.Build(); app.MapHealthChecks("/healthz"); app.Run();

Docker HEALTHCHECK

Docker 提供內(nèi)建 HEALTHCHECK 指示詞,可用來檢查使用基本健康狀態(tài)檢查組態(tài)的應(yīng)用程式狀態(tài):

HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit

上述範(fàn)例會使用 curl,以在 /healthz 針對健康情況檢查端點(diǎn)提出 HTTP 要求。 curl 未包括在 .NET Linux 容器映像中,但可以在 Dockerfile 中安裝必要套件來進(jìn)行新增。 根據(jù) Alpine Linux 來使用映像的容器可以使用所包括的 wget 來取代 curl。

建立健康狀態(tài)檢查

健康狀態(tài)檢查是藉由實(shí)作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態(tài)為 Healthy、Degraded 或 Unhealthy 的 HealthCheckResult。 結(jié)果會寫成具有可設(shè)定狀態(tài)碼的純文字回應(yīng)。 健康情況檢查選項(xiàng)小節(jié)中會描述設(shè)定。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。

下列範(fàn)例示範(fàn)健康情況檢查的配置:

public class SampleHealthCheck : IHealthCheck { public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { var isHealthy = true; // ... if (isHealthy) { return Task.FromResult( HealthCheckResult.Healthy("A healthy result.")); } return Task.FromResult( new HealthCheckResult( context.Registration.FailureStatus, "An unhealthy result.")); } }

健康情況檢查的邏輯放在 CheckHealthAsync 方法中。 上述範(fàn)例會將虛擬變數(shù) isHealthy 設(shè)定為 true。 如果 isHealthy 的值設(shè)定為 false,則會傳回 HealthCheckRegistration.FailureStatus 狀態(tài)。

如果 CheckHealthAsync 在檢查期間擲回例外狀況,則會傳回其 HealthReportEntry.Status 設(shè)定為 FailureStatus 的新 HealthReportEntry。 此狀態(tài)是由 AddCheck 所定義 (請參閱登錄健康情況檢查服務(wù)一節(jié)),並包括造成檢查失敗的內(nèi)部例外狀況。 Description 會設(shè)定為例外狀況的訊息。

登錄健康狀態(tài)檢查服務(wù)

若要登錄健康情況檢查服務(wù),請在 Program.cs 中呼叫 AddCheck:

builder.Services.AddHealthChecks() .AddCheck<SampleHealthCheck>("Sample");

下列範(fàn)例中所顯示的 AddCheck 多載會設(shè)定在健康狀態(tài)檢查報告失敗時所要報告的失敗狀態(tài) (HealthStatus)。 如果將失敗狀態(tài)設(shè)定為 null (預(yù)設(shè)),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態(tài)檢查實(shí)作採用此設(shè)定,則當(dāng)健康狀態(tài)檢查失敗時,應(yīng)用程式就會強(qiáng)制程式庫指出失敗狀態(tài)。

「標(biāo)記」可以用來篩選健康情況檢查。 標(biāo)記會在篩選健康情況檢查小節(jié)中予以描述。

builder.Services.AddHealthChecks() .AddCheck<SampleHealthCheck>( "Sample", failureStatus: HealthStatus.Degraded, tags: new[] { "sample" });

AddCheck 也可以執(zhí)行匿名函式。 在下列範(fàn)例中,健康情況檢查一律會傳回狀況良好結(jié)果:

builder.Services.AddHealthChecks() .AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));

呼叫 AddTypeActivatedCheck,以將引數(shù)傳遞至健康情況檢查實(shí)作。 在下列範(fàn)例中,啟用類型的健康情況檢查會在其建構(gòu)函式中接受整數(shù)和字串:

public class SampleHealthCheckWithArgs : IHealthCheck { private readonly int _arg1; private readonly string _arg2; public SampleHealthCheckWithArgs(int arg1, string arg2) => (_arg1, _arg2) = (arg1, arg2); public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { // ... return Task.FromResult(HealthCheckResult.Healthy("A healthy result.")); } }

若要登錄上述健康情況檢查,請使用傳遞為引數(shù)的整數(shù)和字串來呼叫 AddTypeActivatedCheck:

builder.Services.AddHealthChecks() .AddTypeActivatedCheck<SampleHealthCheckWithArgs>( "Sample", failureStatus: HealthStatus.Degraded, tags: new[] { "sample" }, args: new object[] { 1, "Arg" });

使用健康情況檢查路由傳送

在 Program.cs 中,使用端點(diǎn) URL 或相對路徑以在端點(diǎn)建立器上呼叫 MapHealthChecks:

app.MapHealthChecks("/healthz");

需要主機(jī)

呼叫 RequireHost,以將一或多個允許的主機(jī)指定給健康情況檢查端點(diǎn)。 主機(jī)應(yīng)該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機(jī):

app.MapHealthChecks("/healthz") .RequireHost("www.contoso.com:5001");

若要限制健康情況檢查端點(diǎn)只在特定連接埠上回應(yīng),請在 RequireHost 呼叫中指定連接埠。 此方式通常用於容器環(huán)境,以公開監(jiān)控服務(wù)的連接埠:

app.MapHealthChecks("/healthz") .RequireHost("*:5001");

若要防止未經(jīng)授權(quán)的用戶端詐騙連接埠,請呼叫 RequireAuthorization:

app.MapHealthChecks("/healthz") .RequireHost("*:5001") .RequireAuthorization();

如需詳細(xì)資訊,請參閱具有 RequireHost 之路由中的主機(jī)比對。

需要授權(quán)

呼叫 RequireAuthorization,以在健康情況檢查要求端點(diǎn)上執(zhí)行授權(quán)中介軟體。 RequireAuthorization 多載接受一或多個授權(quán)原則。 如果未提供原則,則會使用預(yù)設(shè)授權(quán)原則:

app.MapHealthChecks("/healthz") .RequireAuthorization();

啟用跨原始來源要求 (CORS)

雖然從瀏覽器手動執(zhí)行健康情況檢查不是常見案例,但是您可以在健康情況檢查端點(diǎn)上呼叫 RequireCors,以啟用 CORS 中介軟體。 RequireCors 多載接受 CORS 原則建立器委派 (CorsPolicyBuilder) 或原則名稱。 如需詳細(xì)資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。

健康狀態(tài)檢查選項(xiàng)

HealthCheckOptions 讓您有機(jī)會自訂健康狀態(tài)檢查行為:

篩選健康狀態(tài)檢查 自訂 HTTP 狀態(tài)碼 隱藏快取標(biāo)頭 自訂輸出

篩選健康狀態(tài)檢查

根據(jù)預(yù)設(shè),健康情況檢查中介軟體會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行健康狀態(tài)檢查子集,請對 Predicate 選項(xiàng)提供傳回布林值的函式。

下列範(fàn)例會篩選健康情況檢查,以只執(zhí)行已標(biāo)記 sample 的檢查:

app.MapHealthChecks("/healthz", new HealthCheckOptions { Predicate = healthCheck => healthCheck.Tags.Contains("sample") });

自訂 HTTP 狀態(tài)碼

您可以使用 ResultStatusCodes 來自訂健康狀態(tài)與 HTTP 狀態(tài)碼的對應(yīng)。 下列 StatusCodes 指派是中介軟體所使用的預(yù)設(shè)值。 變更狀態(tài)碼值,以符合您的需求:

app.MapHealthChecks("/healthz", new HealthCheckOptions { ResultStatusCodes = { [HealthStatus.Healthy] = StatusCodes.Status200OK, [HealthStatus.Degraded] = StatusCodes.Status200OK, [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable } });

隱藏快取標(biāo)頭

AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標(biāo)頭新增至探查回應(yīng),以防止回應(yīng)快取。 如果值為 false (預(yù)設(shè)),則中介軟體會設(shè)定或覆寫 Cache-Control、Expires 和 Pragma 標(biāo)頭,以防止回應(yīng)快取。 如果值為 true,則中介軟體不會修改回應(yīng)的快取標(biāo)頭:

app.MapHealthChecks("/healthz", new HealthCheckOptions { AllowCachingResponses = true });

自訂輸出

若要自訂健康情況檢查報告的輸出,請將 HealthCheckOptions.ResponseWriter 屬性設(shè)定為可寫入回應(yīng)的委派:

app.MapHealthChecks("/healthz", new HealthCheckOptions { ResponseWriter = WriteResponse });

預(yù)設(shè)委派會使用字串值 HealthReport.Status 寫入基本純文字回應(yīng)。 下列自訂委派會使用 System.Text.Json來輸出自訂 JSON 回應(yīng):

private static Task WriteResponse(HttpContext context, HealthReport healthReport) { context.Response.ContentType = "application/json; charset=utf-8"; var options = new JsonWriterOptions { Indented = true }; using var memoryStream = new MemoryStream(); using (var jsonWriter = new Utf8JsonWriter(memoryStream, options)) { jsonWriter.WriteStartObject(); jsonWriter.WriteString("status", healthReport.Status.ToString()); jsonWriter.WriteStartObject("results"); foreach (var healthReportEntry in healthReport.Entries) { jsonWriter.WriteStartObject(healthReportEntry.Key); jsonWriter.WriteString("status", healthReportEntry.Value.Status.ToString()); jsonWriter.WriteString("description", healthReportEntry.Value.Description); jsonWriter.WriteStartObject("data"); foreach (var item in healthReportEntry.Value.Data) { jsonWriter.WritePropertyName(item.Key); JsonSerializer.Serialize(jsonWriter, item.Value, item.Value?.GetType() ?? typeof(object)); } jsonWriter.WriteEndObject(); jsonWriter.WriteEndObject(); } jsonWriter.WriteEndObject(); jsonWriter.WriteEndObject(); } return context.Response.WriteAsync( Encoding.UTF8.GetString(memoryStream.ToArray())); }

健康情況檢查 API 未提供複雜 JSON 傳回格式的內(nèi)建支援,因?yàn)榇烁袷绞悄x擇的監(jiān)控系統(tǒng)所特有。 視需要,自訂上述範(fàn)例中的回應(yīng)。 如需使用 System.Text.Json進(jìn)行 JSON 序列化的詳細(xì)資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。

資料庫探查

健康狀態(tài)檢查可指定資料庫查詢以布林測試方式來執(zhí)行,藉此指出資料庫是否正?;貞?yīng)。

AspNetCore.Diagnostics.HealthChecks,一種適用於 ASP.NET Core 應(yīng)用程式的健康情況檢查程式庫,包括針對 SQL Server 資料庫所執(zhí)行的健康情況檢查。 AspNetCore.Diagnostics.HealthChecks 會對資料庫執(zhí)行 SELECT 1 查詢,以確認(rèn)資料庫連線狀況良好。

警告

使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風(fēng)險。 在大部分情況下,不需要執(zhí)行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發(fā)現(xiàn)有必要執(zhí)行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1。

若要使用此 SQL Server 健康情況檢查,請包括 AspNetCore.HealthChecks.SqlServer NuGet 套件的套件參考。 下列範(fàn)例會登錄 SQL Server 健康情況檢查:

builder.Services.AddHealthChecks() .AddSqlServer( builder.Configuration.GetConnectionString("DefaultConnection"));

Entity Framework Core DbContext 探查

DbContext 檢查會確認(rèn)應(yīng)用程式是否可以與針對 EF CoreDbContext 所設(shè)定的資料庫通訊。 應(yīng)用程式支援 DbContext 檢查:

使用 Entity Framework (EF) Core。 包括 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore NuGet 套件的套件參考。

AddDbContextCheck 會登錄 DbContext 的健康狀態(tài)檢查。 DbContext 會以 TContext 形式提供給方法。 多載可用來設(shè)定失敗狀態(tài)、標(biāo)籤和自訂測試查詢。

預(yù)設(shè)情況:

DbContextHealthCheck 會呼叫 EF Core 的 CanConnectAsync 方法。 您可以自訂使用 AddDbContextCheck 方法多載檢查健康狀態(tài)時所要執(zhí)行的作業(yè)。 健康狀態(tài)檢查的名稱是 TContext 類型的名稱。

下列範(fàn)例會登錄 DbContext 和相關(guān)聯(lián)的 DbContextHealthCheck:

builder.Services.AddDbContext<SampleDbContext>(options => options.UseSqlServer( builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddHealthChecks() .AddDbContextCheck<SampleDbContext>();

個別的整備度與活躍度探查

在某些裝載案例中,會使用一組健康情況檢查來區(qū)分兩個應(yīng)用程式狀態(tài):

「整備」指出應(yīng)用程式是否正在正常執(zhí)行,但尚未準(zhǔn)備好接收要求。 「活躍度」指出應(yīng)用程式是否已當(dāng)機(jī),而且必須重新予以啟動。

請考慮下列範(fàn)例:應(yīng)用程式在準(zhǔn)備好處理要求之前必須下載大型設(shè)定檔。 如果初始下載失敗,則我們不想要重新啟動應(yīng)用程式,因?yàn)閼?yīng)用程式可以重試下載檔案數(shù)次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執(zhí)行其他檢查。 我們也想要防止在設(shè)定檔下載成功之前將要求傳送至應(yīng)用程式。 除非下載成功,而且應(yīng)用程式準(zhǔn)備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」?fàn)顟B(tài)。

下列背景工作會模擬大約需要 15 秒的啟動處理序。 完成後,工作會將 StartupHealthCheck.StartupCompleted 屬性設(shè)定為 True:

public class StartupBackgroundService : BackgroundService { private readonly StartupHealthCheck _healthCheck; public StartupBackgroundService(StartupHealthCheck healthCheck) => _healthCheck = healthCheck; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // Simulate the effect of a long-running task. await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken); _healthCheck.StartupCompleted = true; } }

StartupHealthCheck 會報告長時間執(zhí)行的啟動工作完成,並公開背景服務(wù)所設(shè)定的 StartupCompleted 屬性:

public class StartupHealthCheck : IHealthCheck { private volatile bool _isReady; public bool StartupCompleted { get => _isReady; set => _isReady = value; } public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { if (StartupCompleted) { return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed.")); } return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running.")); } }

健康狀態(tài)檢查是 Program.cs 中使用 AddCheck 隨託管服務(wù)一起登錄。 因?yàn)樗b載服務(wù)必須在健康情況檢查上設(shè)定此屬性,所以也會在服務(wù)容器中將健康情況檢查登錄為單一資料庫:

builder.Services.AddHostedService<StartupBackgroundService>(); builder.Services.AddSingleton<StartupHealthCheck>(); builder.Services.AddHealthChecks() .AddCheck<StartupHealthCheck>( "Startup", tags: new[] { "ready" });

若要建立兩個不同的健康情況檢查端點(diǎn),請呼叫 MapHealthChecks 兩次:

app.MapHealthChecks("/healthz/ready", new HealthCheckOptions { Predicate = healthCheck => healthCheck.Tags.Contains("ready") }); app.MapHealthChecks("/healthz/live", new HealthCheckOptions { Predicate = _ => false });

上述範(fàn)例會建立下列健康情況檢查端點(diǎn):

/healthz/ready 用於整備檢查。 整備檢查會將健康情況檢查篩選為已標(biāo)記 ready 的檢查。 /healthz/live 用於活躍度檢查。 活躍度檢查會在 HealthCheckOptions.Predicate 委派中傳回 false,以篩選出所有健康情況檢查。 如需篩選健康情況檢查的詳細(xì)資訊,請參閱本文中的篩選健康情況檢查。

啟動工作完成之前,/healthz/ready 端點(diǎn)會回報 Unhealthy 狀態(tài)。 啟動工作完成之後,此端點(diǎn)會回報 Healthy 狀態(tài)。 /healthz/live 端點(diǎn)會排除所有檢查,並將所有呼叫的狀態(tài)都回報為 Healthy。

Kubernetes 範(fàn)例

使用個別的整備度與活躍度檢查在 Kubernetes 之類的環(huán)境中很有用。 在 Kubernetes 中,應(yīng)用程式可能需要先執(zhí)行耗時的啟動工作,才能接受要求 (例如基礎(chǔ)資料庫可用性測試)。 使用個別的檢查可讓協(xié)調(diào)器區(qū)分應(yīng)用程式是否為正常運(yùn)作但尚未準(zhǔn)備好,或應(yīng)用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細(xì)資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設(shè)定活躍度與整備度探查)。

下列範(fàn)例示範(fàn) Kubernetes 整備度探查組態(tài):

spec: template: spec: readinessProbe: # an http probe httpGet: path: /healthz/ready port: 80 # length of time to wait for a pod to initialize # after pod startup, before applying health checking initialDelaySeconds: 30 timeoutSeconds: 1 ports: - containerPort: 80

發(fā)佈健康狀態(tài)檢查程式庫

若要發(fā)佈健康狀態(tài)檢查作為程式庫:

寫入健康狀態(tài)檢查,將 IHealthCheck 介面當(dāng)做獨(dú)立類別來實(shí)作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項(xiàng)來存取組態(tài)資料。

使用取用應(yīng)用程式在其 Program.cs 方法中呼叫的參數(shù),來寫入延伸模組。 請考慮下列範(fàn)例健康情況檢查,而此檢查接受 arg1 和 arg2 作為建構(gòu)函式參數(shù):

public SampleHealthCheckWithArgs(int arg1, string arg2) => (_arg1, _arg2) = (arg1, arg2);

上述簽章指出健康情況檢查需要自訂資料,才能處理健康情況檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態(tài)檢查時,用來建立健康狀態(tài)檢查執(zhí)行個體。 在下列範(fàn)例中,呼叫端會指定:

arg1:健康情況檢查的整數(shù)資料點(diǎn)。 arg2:健康情況檢查的字串引數(shù)。 name:選用的健康情況檢查名稱。 如果 null,則會使用預(yù)設(shè)值。 failureStatus:選用的 HealthStatus,其回報失敗狀態(tài)。 如果為 null,則會使用 HealthStatus.Unhealthy。 tags:標(biāo)記的選用 IEnumerable<string> 集合。

public static class SampleHealthCheckBuilderExtensions { private const string DefaultName = "Sample"; public static IHealthChecksBuilder AddSampleHealthCheck( this IHealthChecksBuilder healthChecksBuilder, int arg1, string arg2, string? name = null, HealthStatus? failureStatus = null, IEnumerable<string>? tags = default) { return healthChecksBuilder.Add( new HealthCheckRegistration( name ?? DefaultName, _ => new SampleHealthCheckWithArgs(arg1, arg2), failureStatus, tags)); } }

健康狀態(tài)檢查發(fā)行者

當(dāng) IHealthCheckPublisher 新增至服務(wù)容器時,健康狀態(tài)檢查系統(tǒng)會定期執(zhí)行健康狀態(tài)檢查,並呼叫 PublishAsync 傳回結(jié)果。 此處理序適用於推送型健康情況監(jiān)控系統(tǒng)案例,而此案例預(yù)期每個處理序都會定期呼叫監(jiān)控系統(tǒng)來判斷健康情況。

HealthCheckPublisherOptions 可讓您設(shè)定:

Delay:初始延遲會在應(yīng)用程式啟動之後且執(zhí)行 IHealthCheckPublisher 執(zhí)行個體之前套用。 啟動後就會套用延遲,但不會套用至後面的反覆項(xiàng)目。 預(yù)設(shè)值是五秒鐘。 Period:IHealthCheckPublisher 執(zhí)行的期間。 預(yù)設(shè)值為 30 秒。 Predicate:如果 Predicate 為 null (預(yù)設(shè)),則健康情況檢查發(fā)行者服務(wù)會執(zhí)行所有已登錄的健康情況檢查。 若要執(zhí)行一部分的健康狀態(tài)檢查,請?zhí)峁┛珊Y選該組檢查的函式。 每個期間都會評估該述詞。 Timeout:執(zhí)行所有 IHealthCheckPublisher 執(zhí)行個體之健康情況檢查的逾時。 若要在沒有逾時的情況下執(zhí)行,請使用 InfiniteTimeSpan。 預(yù)設(shè)值為 30 秒。

下列範(fàn)例示範(fàn)健康情況發(fā)行者的配置:

public class SampleHealthCheckPublisher : IHealthCheckPublisher { public Task PublishAsync(HealthReport report, CancellationToken cancellationToken) { if (report.Status == HealthStatus.Healthy) { // ... } else { // ... } return Task.CompletedTask; } }

HealthCheckPublisherOptions 類別提供屬性來設(shè)定健康情況檢查發(fā)行者的行為。

下列範(fàn)例會將健康情況檢查發(fā)行者登錄為單一資料庫,並設(shè)定 HealthCheckPublisherOptions:

builder.Services.Configure<HealthCheckPublisherOptions>(options => { options.Delay = TimeSpan.FromSeconds(2); options.Predicate = healthCheck => healthCheck.Tags.Contains("sample"); }); builder.Services.AddSingleton<IHealthCheckPublisher, SampleHealthCheckPublisher>();

相依性插入和健康情況檢查

您可以使用相依性插入來取用健康情況檢查類別內(nèi)特定 Type 的執(zhí)行個體。 相依性插入適用於將選項(xiàng)或全域設(shè)定插入至健康情況檢查。 使用相依性插入「不」是設(shè)定健康情況檢查的常見案例。 通常,每個健康情況檢查都是專屬於實(shí)際測試,並且使用 IHealthChecksBuilder 擴(kuò)充方法進(jìn)行設(shè)定。

下列範(fàn)例顯示可透過相依性插入來擷取設(shè)定物件的範(fàn)例健康情況檢查:

public class SampleHealthCheckWithDI : IHealthCheck { private readonly SampleHealthCheckWithDiConfig _config; public SampleHealthCheckWithDI(SampleHealthCheckWithDiConfig config) => _config = config; public Task<HealthCheckResult> CheckHealthAsync( HealthCheckContext context, CancellationToken cancellationToken = default) { var isHealthy = true; // use _config ... if (isHealthy) { return Task.FromResult( HealthCheckResult.Healthy("A healthy result.")); } return Task.FromResult( new HealthCheckResult( context.Registration.FailureStatus, "An unhealthy result.")); } }

SampleHealthCheckWithDiConfig 和健康情況檢查需要新增至服務(wù)容器:

builder.Services.AddSingleton<SampleHealthCheckWithDiConfig>(new SampleHealthCheckWithDiConfig { BaseUriToCheck = new Uri("https://sample.contoso.com/api/") }); builder.Services.AddHealthChecks() .AddCheck<SampleHealthCheckWithDI>( "With Dependency Injection", tags: new[] { "inject" });

UseHealthChecks 與MapHealthChecks

有兩種方式可讓呼叫端存取健康情況檢查:

UseHealthChecks 會登錄中介軟體來處理中介軟體管線中的健康情況檢查要求。 MapHealthChecks 會登錄健康情況檢查端點(diǎn)。 端點(diǎn)會與應(yīng)用程式中的其他端點(diǎn)進(jìn)行比對和執(zhí)行。

使用 MapHealthChecks 優(yōu)於 UseHealthChecks 的優(yōu)點(diǎn)是能夠使用端點(diǎn)感知中介軟體 (例如授權(quán)),並更精細(xì)地控制比對原則。 使用 UseHealthChecks 優(yōu)於 MapHealthChecks 的主要優(yōu)點(diǎn)是確切控制中介軟體管線中執(zhí)行健康情況檢查的位置。

UseHealthChecks:

在要求符合健康情況檢查端點(diǎn)時終止管線。 最短線路可避免不必要的工作,因此經(jīng)常使用 (例如記錄和其他中介軟體)。 主要用於在管線中設(shè)定健康情況檢查中介軟體。 可以比對連接埠上的任何路徑與 null 或空白 PathString。 允許在針對所指定連接埠所提出的任何要求上執(zhí)行健康情況檢查。 原始程式碼

MapHealthChecks 允許:

對應(yīng)特定路由或端點(diǎn)以進(jìn)行健康情況檢查。 自訂可存取健康情況檢查端點(diǎn)的 URL 或路徑。 使用不同的路由或設(shè)定來對應(yīng)多個健康情況檢查端點(diǎn)。 多個端點(diǎn)支援: 針對不同類型的健康情況檢查或元件啟用不同的端點(diǎn)。 用來區(qū)分應(yīng)用程式健康情況的不同層面,或?qū)⑻囟ㄔO(shè)定套用至健康情況檢查的子集。 原始程式碼

其他資源

檢視或下載範(fàn)例程式碼 (英文) (如何下載)您可以在 GitHub 上找到此內(nèi)容的來源,在其中建立和檢閱問題和提取要求。 如需詳細(xì)資訊,請參閱我們的參與者指南。

其他資源

事件

加入我們在 FabCon Vegas

3月31日 下午11時 - 4月2日 下午11時

最終Microsoft Fabric、Power BI、SQL 和 AI 社群主導(dǎo)的活動。 2025 年 3 月 31 日至 4 月 2 日。

立即註冊

本文內(nèi)容

相關(guān)知識

健康體檢,哪些項(xiàng)目該查
簡單易行的肌肉骨骼健康保護(hù)方法
生態(tài)環(huán)境部發(fā)佈《“十四五”環(huán)境健康工作規(guī)劃》
報告稱中國近九成城市“亞健康”?北京環(huán)境排名靠后
醫(yī)思健康醫(yī)療中心 EC Healthcare Medical Centre
去年以來江蘇立案生態(tài)環(huán)境民事公益訴訟達(dá)590件
這份心理調(diào)適指南 送給高考後的你們
中華人民共和國生態(tài)環(huán)境部令(第32號)  排污許可管理辦法
衛(wèi)生部日前發(fā)佈孕産期保健工作管理辦法及規(guī)範(fàn)
中醫(yī)健康管理

網(wǎng)址: ASP.NET Core 中的健康狀態(tài)檢查 http://www.u1s5d6.cn/newsview496090.html

推薦資訊