事件
Power BI DataViz World Championships
2月14日 下午4時 - 3月31日 下午4時
4 次參賽機會,有機會贏得會議套裝行程,現場參與在拉斯維加斯舉行的總決賽
進一步了解作者:Glenn Condron 和 Juergen Gutsch
備註
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應用程式基礎結構元件的健康情況。
應用程式會將健康狀態檢查公開為 HTTP 端點。 您可以針對各種即時監控案例來設定健康情況檢查端點:
健康情況檢查通常會與外部監控服務或容器協調器搭配使用,來檢查應用程式的狀態。 將健康狀態檢查新增至應用程式之前,請決定要使用的監控系統。 監控系統會指定要建立哪些健康狀態檢查類型,以及如何設定其端點。
對於許多應用程式,報告應用程式是否可處理要求的基本健康狀態探查組態 (「活躍度」),便足以探索應用程式的狀態。
基本設定會登錄健康情況檢查服務,並呼叫健康情況檢查中介軟體以在具有健康情況回應的 URL 端點做出回應。 預設並未登錄特定健康狀態檢查來測試任何特定相依性或子系統。 如果應用程式可以在健康情況端點 URL 做出回應,則視為狀況良好。 預設回應寫入器會將 HealthStatus 以純文字回應形式寫入至用戶端。 HealthStatus
是 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy。
在 Program.cs
中,使用 AddHealthChecks 登錄健康狀態檢查服務。 呼叫 MapHealthChecks 來建立健康情況檢查端點。
下列範例會在 /healthz
建立健康情況檢查端點:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/healthz");
app.Run();
Docker 提供內建 HEALTHCHECK
指示詞,可用來檢查使用基本健康狀態檢查組態的應用程式狀態:
HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit
上述範例會使用 curl
,以在 /healthz
針對健康情況檢查端點提出 HTTP 要求。 curl
未包括在 .NET Linux 容器映像中,但可以在 Dockerfile 中安裝必要套件來進行新增。 根據 Alpine Linux 來使用映像的容器可以使用所包括的 wget
來取代 curl
。
健康狀態檢查是藉由實作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態為 Healthy
、Degraded
或 Unhealthy
的 HealthCheckResult。 結果會寫成具有可設定狀態碼的純文字回應。 健康情況檢查選項小節中會描述設定。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。
下列範例示範健康情況檢查的配置:
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 方法中。 上述範例會將虛擬變數 isHealthy
設定為 true
。 如果 isHealthy
的值設定為 false
,則會傳回 HealthCheckRegistration.FailureStatus 狀態。
如果 CheckHealthAsync 在檢查期間擲回例外狀況,則會傳回其 HealthReportEntry.Status 設定為 FailureStatus 的新 HealthReportEntry。 此狀態是由 AddCheck 所定義 (請參閱登錄健康情況檢查服務一節),並包括造成檢查失敗的內部例外狀況。 Description 會設定為例外狀況的訊息。
若要登錄健康情況檢查服務,請在 Program.cs
中呼叫 AddCheck:
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>("Sample");
下列範例中所顯示的 AddCheck 多載會設定在健康狀態檢查報告失敗時所要報告的失敗狀態 (HealthStatus)。 如果將失敗狀態設定為 null
(預設),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態檢查實作採用此設定,則當健康狀態檢查失敗時,應用程式就會強制程式庫指出失敗狀態。
「標記」可以用來篩選健康情況檢查。 標記會在篩選健康情況檢查小節中予以描述。
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" });
AddCheck 也可以執行匿名函式。 在下列範例中,健康情況檢查一律會傳回狀況良好結果:
builder.Services.AddHealthChecks()
.AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));
呼叫 AddTypeActivatedCheck,以將引數傳遞至健康情況檢查實作。 在下列範例中,啟用類型的健康情況檢查會在其建構函式中接受整數和字串:
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."));
}
}
若要登錄上述健康情況檢查,請使用傳遞為引數的整數和字串來呼叫 AddTypeActivatedCheck
:
builder.Services.AddHealthChecks()
.AddTypeActivatedCheck<SampleHealthCheckWithArgs>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" },
args: new object[] { 1, "Arg" });
在 Program.cs
中,使用端點 URL 或相對路徑以在端點建立器上呼叫 MapHealthChecks
:
app.MapHealthChecks("/healthz");
呼叫 RequireHost
,以將一或多個允許的主機指定給健康情況檢查端點。 主機應該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機:
app.MapHealthChecks("/healthz")
.RequireHost("www.contoso.com:5001");
若要限制健康情況檢查端點只在特定連接埠上回應,請在 RequireHost
呼叫中指定連接埠。 此方式通常用於容器環境,以公開監控服務的連接埠:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001");
警告
依賴於主機標頭的 API (例如 HttpRequest.Host 和 RequireHost) 可能會受到用戶端的詐騙。
若要防止主機和連接埠詐騙,請使用下列其中一種方式:
若要防止未經授權的用戶端詐騙連接埠,請呼叫 RequireAuthorization:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001")
.RequireAuthorization();
如需詳細資訊,請參閱具有 RequireHost 之路由中的主機比對。
呼叫 RequireAuthorization,以在健康情況檢查要求端點上執行授權中介軟體。 RequireAuthorization
多載接受一或多個授權原則。 如果未提供原則,則會使用預設授權原則:
app.MapHealthChecks("/healthz")
.RequireAuthorization();
雖然從瀏覽器手動執行健康情況檢查不是常見案例,但是您可以在健康情況檢查端點上呼叫 RequireCors
,以啟用 CORS 中介軟體。 RequireCors
多載接受 CORS 原則建立器委派 (CorsPolicyBuilder
) 或原則名稱。 如需詳細資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。
HealthCheckOptions 讓您有機會自訂健康狀態檢查行為:
根據預設,健康情況檢查中介軟體會執行所有已登錄的健康情況檢查。 若要執行健康狀態檢查子集,請對 Predicate 選項提供傳回布林值的函式。
下列範例會篩選健康情況檢查,以只執行已標記 sample
的檢查:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("sample")
});
您可以使用 ResultStatusCodes 來自訂健康狀態與 HTTP 狀態碼的對應。 下列 StatusCodes 指派是中介軟體所使用的預設值。 變更狀態碼值,以符合您的需求:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標頭新增至探查回應,以防止回應快取。 如果值為 false
(預設),則中介軟體會設定或覆寫 Cache-Control
、Expires
和 Pragma
標頭,以防止回應快取。 如果值為 true
,則中介軟體不會修改回應的快取標頭:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
AllowCachingResponses = true
});
若要自訂健康情況檢查報告的輸出,請將 HealthCheckOptions.ResponseWriter 屬性設定為可寫入回應的委派:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResponseWriter = WriteResponse
});
預設委派會使用字串值 HealthReport.Status
寫入基本純文字回應。 下列自訂委派會使用 System.Text.Json來輸出自訂 JSON 回應:
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 傳回格式的內建支援,因為此格式是您所選擇的監控系統所特有。 視需要,自訂上述範例中的回應。 如需使用 System.Text.Json
進行 JSON 序列化的詳細資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。
健康狀態檢查可指定資料庫查詢以布林測試方式來執行,藉此指出資料庫是否正常回應。
AspNetCore.Diagnostics.HealthChecks
,一種適用於 ASP.NET Core 應用程式的健康情況檢查程式庫,包括針對 SQL Server 資料庫所執行的健康情況檢查。 AspNetCore.Diagnostics.HealthChecks
會對資料庫執行 SELECT 1
查詢,以確認資料庫連線狀況良好。
警告
使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風險。 在大部分情況下,不需要執行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發現有必要執行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1
。
若要使用此 SQL Server 健康情況檢查,請包括 AspNetCore.HealthChecks.SqlServer
NuGet 套件的套件參考。 下列範例會登錄 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);
備註
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
DbContext
檢查會確認應用程式是否可以與針對 EF CoreDbContext
所設定的資料庫通訊。 應用程式支援 DbContext
檢查:
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
NuGet 套件的套件參考。AddDbContextCheck 會登錄 DbContext 的健康狀態檢查。 DbContext
會以 TContext
形式提供給方法。 多載可用來設定失敗狀態、標籤和自訂測試查詢。
預設情況:
DbContextHealthCheck
會呼叫 EF Core 的 CanConnectAsync
方法。 您可以自訂使用 AddDbContextCheck
方法多載檢查健康狀態時所要執行的作業。TContext
類型的名稱。下列範例會登錄 DbContext
和相關聯的 DbContextHealthCheck
:
builder.Services.AddDbContext<SampleDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddHealthChecks()
.AddDbContextCheck<SampleDbContext>();
在某些裝載案例中,會使用一組健康情況檢查來區分兩個應用程式狀態:
請考慮下列範例:應用程式在準備好處理要求之前必須下載大型設定檔。 如果初始下載失敗,則我們不想要重新啟動應用程式,因為應用程式可以重試下載檔案數次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執行其他檢查。 我們也想要防止在設定檔下載成功之前將要求傳送至應用程式。 除非下載成功,而且應用程式準備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」狀態。
下列背景工作會模擬大約需要 15 秒的啟動處理序。 完成後,工作會將 StartupHealthCheck.StartupCompleted
屬性設定為 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
會報告長時間執行的啟動工作完成,並公開背景服務所設定的 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."));
}
}
健康狀態檢查是 Program.cs
中使用 AddCheck 隨託管服務一起登錄。 因為所裝載服務必須在健康情況檢查上設定此屬性,所以也會在服務容器中將健康情況檢查登錄為單一資料庫:
builder.Services.AddHostedService<StartupBackgroundService>();
builder.Services.AddSingleton<StartupHealthCheck>();
builder.Services.AddHealthChecks()
.AddCheck<StartupHealthCheck>(
"Startup",
tags: new[] { "ready" });
若要建立兩個不同的健康情況檢查端點,請呼叫 MapHealthChecks
兩次:
app.MapHealthChecks("/healthz/ready", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("ready")
});
app.MapHealthChecks("/healthz/live", new HealthCheckOptions
{
Predicate = _ => false
});
上述範例會建立下列健康情況檢查端點:
/healthz/ready
用於整備檢查。 整備檢查會將健康情況檢查篩選為已標記 ready
的檢查。/healthz/live
用於活躍度檢查。 活躍度檢查會在 HealthCheckOptions.Predicate 委派中傳回 false
,以篩選出所有健康情況檢查。 如需篩選健康情況檢查的詳細資訊,請參閱本文中的篩選健康情況檢查。啟動工作完成之前,/healthz/ready
端點會回報 Unhealthy
狀態。 啟動工作完成之後,此端點會回報 Healthy
狀態。 /healthz/live
端點會排除所有檢查,並將所有呼叫的狀態都回報為 Healthy
。
使用個別的整備度與活躍度檢查在 Kubernetes 之類的環境中很有用。 在 Kubernetes 中,應用程式可能需要先執行耗時的啟動工作,才能接受要求 (例如基礎資料庫可用性測試)。 使用個別的檢查可讓協調器區分應用程式是否為正常運作但尚未準備好,或應用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設定活躍度與整備度探查)。
下列範例示範 Kubernetes 整備度探查組態:
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
若要發佈健康狀態檢查作為程式庫:
寫入健康狀態檢查,將 IHealthCheck 介面當做獨立類別來實作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項來存取組態資料。
使用取用應用程式在其 Program.cs
方法中呼叫的參數,來寫入延伸模組。 請考慮下列範例健康情況檢查,而此檢查接受 arg1
和 arg2
作為建構函式參數:
public SampleHealthCheckWithArgs(int arg1, string arg2)
=> (_arg1, _arg2) = (arg1, arg2);
上述簽章指出健康情況檢查需要自訂資料,才能處理健康情況檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態檢查時,用來建立健康狀態檢查執行個體。 在下列範例中,呼叫端會指定:
arg1
:健康情況檢查的整數資料點。arg2
:健康情況檢查的字串引數。name
:選用的健康情況檢查名稱。 如果 null
,則會使用預設值。failureStatus
:選用的 HealthStatus,其回報失敗狀態。 如果為 null
,則會使用 HealthStatus.Unhealthy。tags
:標記的選用 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));
}
}
當 IHealthCheckPublisher 新增至服務容器時,健康狀態檢查系統會定期執行健康狀態檢查,並呼叫 PublishAsync 傳回結果。 此處理序適用於推送型健康情況監控系統案例,而此案例預期每個處理序都會定期呼叫監控系統來判斷健康情況。
HealthCheckPublisherOptions 可讓您設定:
null
(預設),則健康情況檢查發行者服務會執行所有已登錄的健康情況檢查。 若要執行一部分的健康狀態檢查,請提供可篩選該組檢查的函式。 每個期間都會評估該述詞。下列範例示範健康情況發行者的配置:
public class SampleHealthCheckPublisher : IHealthCheckPublisher
{
public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
{
if (report.Status == HealthStatus.Healthy)
{
// ...
}
else
{
// ...
}
return Task.CompletedTask;
}
}
HealthCheckPublisherOptions 類別提供屬性來設定健康情況檢查發行者的行為。
下列範例會將健康情況檢查發行者登錄為單一資料庫,並設定 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
:
Delay
和 Period
可以在每個 HealthCheckRegistration 上個別設定。 當您想要以與 HealthCheckPublisherOptions 中所設定的期間不同的速率執行一些健康情況檢查時,這非常有用。
下列程式碼會設定 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();
您可以使用相依性插入來取用健康情況檢查類別內特定 Type
的執行個體。 相依性插入適用於將選項或全域設定插入至健康情況檢查。 使用相依性插入「不」是設定健康情況檢查的常見案例。 通常,每個健康情況檢查都是專屬於實際測試,並且使用 IHealthChecksBuilder
擴充方法進行設定。
下列範例顯示可透過相依性插入來擷取設定物件的範例健康情況檢查:
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
和健康情況檢查需要新增至服務容器:
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" });
有兩種方式可讓呼叫端存取健康情況檢查:
使用 MapHealthChecks
優於 UseHealthChecks
的優點是能夠使用端點感知中介軟體 (例如授權),並更精細地控制比對原則。 使用 UseHealthChecks
優於 MapHealthChecks
的主要優點是確切控制中介軟體管線中執行健康情況檢查的位置。
null
或空白 PathString
。 允許在針對所指定連接埠所提出的任何要求上執行健康情況檢查。MapHealthChecks 允許:
app.MapHealthChecks("/healthz").ShortCircuit();
。 如需詳細資訊,請參閱路由之後尋找中介軟體的最短路徑。備註
本文部分是透過人工智慧協助建立的。 發佈之前,請視需要進行作者檢閱並修訂內容。 請參閱我們在 Microsoft Learn 中使用 AI 產生的內容的原則。
ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應用程式基礎結構元件的健康情況。
應用程式會將健康狀態檢查公開為 HTTP 端點。 您可以針對各種即時監控案例來設定健康情況檢查端點:
檢視或下載範例程式碼 \(英文\) (如何下載)
範例應用程式包括本文中所述的案例範例。 若要在指定的案例中執行範例應用程式,請在命令殼層中使用來自專案資料夾的 dotnet run 命令。 如需如何使用範例應用程式的詳細資料,請參閱範例應用程式的 README.md
檔案和本文中的案例描述。
健康情況檢查通常會與外部監控服務或容器協調器搭配使用,來檢查應用程式的狀態。 將健康狀態檢查新增至應用程式之前,請決定要使用的監控系統。 監控系統會指定要建立哪些健康狀態檢查類型,以及如何設定其端點。
ASP.NET Core 應用程式會隱含參考 Microsoft.AspNetCore.Diagnostics.HealthChecks
套件。 若要使用 Entity Framework Core 來執行健康情況檢查,請新增 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
套件的參考。
範例應用程式提供啟動程式碼,來示範數個案例的健康狀態檢查。 資料庫探查案例使用 AspNetCore.Diagnostics.HealthChecks
來檢查資料庫連線的健康情況。 DbContext 探查案例使用 EF CoreDbContext
來檢查資料庫。 為了探索資料庫案例,範例應用程式會:
appsettings.json
檔案中提供其連接字串。備註
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
另一個健康狀態檢查案例示範如何將健康狀態檢查篩選至管理連接埠。 範例應用程式需要您建立 Properties/launchSettings.json
檔案,而此檔案包括管理 URL 和管理連接埠。 如需詳細資訊,請參閱依連接埠篩選一節。
對於許多應用程式,報告應用程式是否可處理要求的基本健康狀態探查組態 (「活躍度」),便足以探索應用程式的狀態。
基本設定會登錄健康情況檢查服務,並呼叫健康情況檢查中介軟體以在具有健康情況回應的 URL 端點做出回應。 預設並未登錄特定健康狀態檢查來測試任何特定相依性或子系統。 如果應用程式可以在健康情況端點 URL 做出回應,則視為狀況良好。 預設回應寫入器會將狀態 (HealthStatus) 以純文字回應形式回寫至用戶端,指出 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy 狀態。
在 Startup.ConfigureServices
中,使用 AddHealthChecks 登錄健康狀態檢查服務。 在 Startup.Configure
中呼叫 MapHealthChecks
,以建立健康情況檢查端點。
在範例應用程式中,是在 /health
(BasicStartup.cs
) 建立健康情況檢查端點:
public class BasicStartup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
}
}
若要使用範例應用程式執行基本組態案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario basic
Docker 提供內建 HEALTHCHECK
指示詞,可用來檢查使用基本健康狀態檢查組態的應用程式狀態:
HEALTHCHECK CMD curl --fail http://localhost:5000/health || exit
健康狀態檢查是藉由實作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態為 Healthy
、Degraded
或 Unhealthy
的 HealthCheckResult。 結果會寫成具有可設定狀態碼的純文字回應 (健康狀態檢查選項一節中將說明如何進行組態)。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。
下列 ExampleHealthCheck
類別示範健康情況檢查的配置。 健康情況檢查邏輯放在 CheckHealthAsync
方法中。 下列範例會將虛擬變數 healthCheckResultHealthy
設定為 true
。 如果 healthCheckResultHealthy
的值設定為 false
,則會傳回 HealthCheckRegistration.FailureStatus 狀態。
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 設定為 FailureStatus 的新 HealthReportEntry (這由 AddCheck 所定義) (請參閱登錄健康情況檢查服務小節),並包括最初造成檢查失敗的內部例外狀況。 Description 會設定為例外狀況的訊息。
在 Startup.ConfigureServices
中使用 AddCheck,以將 ExampleHealthCheck
類型新增至健康情況檢查服務:
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>("example_health_check");
下列範例中所顯示的 AddCheck 多載會設定在健康狀態檢查報告失敗時所要報告的失敗狀態 (HealthStatus)。 如果將失敗狀態設定為 null
(預設),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態檢查實作採用此設定,則當健康狀態檢查失敗時,應用程式就會強制程式庫指出失敗狀態。
您可以使用「標籤」來篩選健康狀態檢查 (篩選健康狀態檢查一節中將進一步說明)。
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>(
"example_health_check",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" });
AddCheck 也可以執行匿名函式。 在下列範例中,健康狀態檢查名稱指定為 Example
,且檢查一律會傳回狀況良好狀態:
services.AddHealthChecks()
.AddCheck("Example", () =>
HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });
呼叫 AddTypeActivatedCheck,以將引數傳遞至健康情況檢查實作。 在下列範例中,TestHealthCheckWithArgs
接受在呼叫 CheckHealthAsync 時使用整數和字串:
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)
{
...
}
}
使用傳遞至實作的整數和字串來呼叫 AddTypeActivatedCheck
,以登錄 TestHealthCheckWithArgs
:
services.AddHealthChecks()
.AddTypeActivatedCheck<TestHealthCheckWithArgs>(
"test",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" },
args: new object[] { 5, "string" });
在 Startup.Configure
中,使用端點 URL 或相對路徑以在端點建立器上呼叫 MapHealthChecks
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
呼叫 RequireHost
,以將一或多個允許的主機指定給健康情況檢查端點。 主機應該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機。
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001");
});
如需詳細資訊,請參閱依連接埠篩選一節。
呼叫 RequireAuthorization
,以在健康情況檢查要求端點上執行授權中介軟體。 RequireAuthorization
多載接受一或多個授權原則。 如果未提供原則,則會使用預設授權原則。
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireAuthorization();
});
雖然從瀏覽器手動執行健康情況檢查不是常見使用案例,但是您可以在健康情況檢查端點上呼叫 RequireCors
,以啟用 CORS 中介軟體。 RequireCors
多載接受 CORS 原則建立器委派 (CorsPolicyBuilder
) 或原則名稱。 如果未提供原則,則會使用預設 CORS 原則。 如需詳細資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。
HealthCheckOptions 讓您有機會自訂健康狀態檢查行為:
根據預設,健康情況檢查中介軟體會執行所有已登錄的健康情況檢查。 若要執行健康狀態檢查子集,請對 Predicate 選項提供傳回布林值的函式。 在下列範例中,會依函式條件陳述式中的標籤 (bar_tag
) 篩選出 Bar
健康狀態檢查。只有在健康狀態檢查的 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 才能執行:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("foo_tag") ||
check.Tags.Contains("baz_tag")
});
});
您可以使用 ResultStatusCodes 來自訂健康狀態與 HTTP 狀態碼的對應。 下列 StatusCodes 指派是中介軟體所使用的預設值。 請變更狀態碼值以符合您的需求。
在 Startup.Configure
中:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
});
AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標頭新增至探查回應,以防止回應快取。 如果值為 false
(預設),則中介軟體會設定或覆寫 Cache-Control
、Expires
和 Pragma
標頭,以防止回應快取。 如果值為 true
,則中介軟體不會修改回應的快取標頭。
在 Startup.Configure
中:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
AllowCachingResponses = true
});
});
在 Startup.Configure
中,將 HealthCheckOptions.ResponseWriter 選項設定為撰寫回應的委派:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResponseWriter = WriteResponse
});
});
預設委派會使用字串值 HealthReport.Status
寫入基本純文字回應。 下列自訂委派會輸出自訂 JSON 回應。
範例應用程式中的第一個範例示範如何使用 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);
}
}
第二個範例示範如何使用 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));
}
在範例應用程式中,註解化 CustomWriterStartup.cs
中的 SYSTEM_TEXT_JSON
前置處理器指示詞,以啟用 WriteResponse
的 Newtonsoft.Json
版本。
健康情況檢查 API 未提供複雜 JSON 傳回格式的內建支援,因為此格式是您所選擇的監控系統所特有。 視需要,自訂上述範例中的回應。 如需使用 System.Text.Json
進行 JSON 序列化的詳細資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。
健康狀態檢查可指定資料庫查詢以布林測試方式來執行,藉此指出資料庫是否正常回應。
範例應用程式使用 AspNetCore.Diagnostics.HealthChecks
(一種適用於 ASP.NET Core 應用程式的健康情況檢查程式庫),以在 SQL Server 資料庫上執行健康情況檢查。 AspNetCore.Diagnostics.HealthChecks
會對資料庫執行 SELECT 1
查詢,以確認資料庫連線狀況良好。
警告
使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風險。 在大部分情況下,不需要執行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發現有必要執行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1
。
包括 AspNetCore.HealthChecks.SqlServer
的套件參考。
在範例應用程式的 appsettings.json
檔案中,提供有效的資料庫連接字串。 應用程式使用名為 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 登錄健康狀態檢查服務。 範例應用程式會使用資料庫連接字串 (DbHealthStartup.cs
) 來呼叫 AddSqlServer
方法:
services.AddHealthChecks()
.AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
}
若要使用範例應用程式執行資料庫探查案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario db
備註
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
DbContext
檢查會確認應用程式是否可以與針對 EF CoreDbContext
所設定的資料庫通訊。 應用程式支援 DbContext
檢查:
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
的套件參考。AddDbContextCheck<TContext>
會登錄 DbContext
的健康狀態檢查。 DbContext
會以 TContext
形式提供給方法。 多載可用來設定失敗狀態、標籤和自訂測試查詢。
預設情況:
DbContextHealthCheck
會呼叫 EF Core 的 CanConnectAsync
方法。 您可以自訂使用 AddDbContextCheck
方法多載檢查健康狀態時所要執行的作業。TContext
類型的名稱。在範例應用程式中,會將 AppDbContext
提供給 AddDbContextCheck
,並在 Startup.ConfigureServices
中登錄為服務 (DbContextHealthStartup.cs
):
services.AddHealthChecks()
.AddDbContextCheck<AppDbContext>();
services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(
Configuration["ConnectionStrings:DefaultConnection"]);
});
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
}
若要使用範例應用程式來執行 DbContext
探查案例,請確認 SQL Server 執行個體中沒有連接字串所指定的資料庫。 如果資料庫存在,請予以刪除。
在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario dbcontext
在應用程式執行之後,對瀏覽器中的 /health
端點提出要求來檢查健康狀態。 資料庫和 AppDbContext
不存在,因此應用程式會提供下列回應:
Unhealthy
觸發範例應用程式以建立資料庫。 對 /createdatabase
提出要求。 應用程式會回應:
Creating the database...
Done!
Navigate to /health to see the health status.
對 /health
端點提出要求。 資料庫和內容存在,因此應用程式會回應:
Healthy
觸發範例應用程式以刪除資料庫。 對 /deletedatabase
提出要求。 應用程式會回應:
Deleting the database...
Done!
Navigate to /health to see the health status.
對 /health
端點提出要求。 應用程式會提供狀況不良回應:
Unhealthy
在某些裝載案例中,會使用一組健康情況檢查來區分兩個應用程式狀態:
請考慮下列範例:應用程式在準備好處理要求之前必須下載大型設定檔。 如果初始下載失敗,則我們不想要重新啟動應用程式,因為應用程式可以重試下載檔案數次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執行其他檢查。 我們也想要防止在設定檔下載成功之前將要求傳送至應用程式。 除非下載成功,而且應用程式準備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」狀態。
範例應用程式包含健康狀態檢查,會在託管服務中長時間執行的啟動工作完成時回報。 StartupHostedServiceHealthCheck
會公開 StartupTaskCompleted
屬性,而裝載的服務可以在其長時間執行的工作完成時,將此屬性設定為 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."));
}
}
裝載的服務 (Services/StartupHostedService
) 會啟動長時間執行的背景工作。 工作完成時,StartupHostedServiceHealthCheck.StartupTaskCompleted
會設定為 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()
{
}
}
健康狀態檢查是 Startup.ConfigureServices
中使用 AddCheck 隨託管服務一起登錄。 因為所裝載服務必須在健康情況檢查上設定此屬性,所以也會在服務容器中登錄健康情況檢查 (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>();
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
。 在範例應用程式中,是在下列位置建立健康情況檢查端點:
/health/ready
用於整備檢查。 整備度檢查使用 ready
標籤來篩選健康狀態檢查。/health/live
用於活躍度檢查。 活躍度檢查是在 HealthCheckOptions.Predicate
中傳回 false
來篩選出 StartupHostedServiceHealthCheck
(如需詳細資訊,請參閱篩選健康情況檢查)在下列範例程式碼中:
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
});
}
若要使用範例應用程式執行整備度/活躍度組態案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario liveness
在瀏覽器中,瀏覽 /health/ready
數次,直到經過 15 秒。 健康狀態檢查報告前 15 秒為 Unhealthy
。 15 秒之後,端點會報告 Healthy
,以反映託管服務長時間執行的工作已完成。
此範例也會建立一個以兩秒延遲執行第一次整備檢查的「健康情況檢查發行者」(IHealthCheckPublisher 實作)。 如需詳細資訊,請參閱健康狀態檢查發行者一節。
使用個別的整備度與活躍度檢查在 Kubernetes 之類的環境中很有用。 在 Kubernetes 中,應用程式可能需要先執行耗時的啟動工作,才能接受要求 (例如基礎資料庫可用性測試)。 使用個別的檢查可讓協調器區分應用程式是否為正常運作但尚未準備好,或應用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設定活躍度與整備度探查)。
下列範例示範 Kubernetes 整備度探查組態:
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
範例應用程式示範透過自訂回應寫入器的記憶體健康狀態檢查。
如果應用程式使用超過指定的記憶體閾值 (在範例應用程式中為 1 GB),MemoryHealthCheck
會報告降級的狀態。 HealthCheckResult 包括應用程式的記憶體回收行程 (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 登錄健康狀態檢查服務。 MemoryHealthCheck
會登錄為服務,而不是將健康狀態檢查傳遞至 AddCheck 以啟用檢查。 所有 IHealthCheck 登錄的服務都可供健康狀態檢查服務和中介軟體使用。 建議將健康狀態檢查服務登錄為單一服務。
在範例應用程式的 CustomWriterStartup.cs
中:
services.AddHealthChecks()
.AddMemoryHealthCheck("memory");
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
。 當健康狀態檢查執行時,會將 WriteResponse
委派提供給 ResponseWriter 屬性以輸出自訂 JSON 回應:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResponseWriter = WriteResponse
});
}
WriteResponse
委派會將 CompositeHealthCheckResult
格式化為 JSON 物件,並產生健康情況檢查回應的 JSON 輸出。 如需詳細資訊,請參閱自訂輸出小節。
若要使用範例應用程式透過自訂回應寫入器輸出執行計量型探查,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario writer
備註
AspNetCore.Diagnostics.HealthChecks
包括計量型健康情況檢查案例,包括磁碟儲存體和最大值活躍度檢查。
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
使用 URL 模式以在 MapHealthChecks
上呼叫 RequireHost
,而此模式指定連接埠來限制針對所指定連接埠的健康情況檢查要求。 此方式通常用於容器環境,以公開監控服務的連接埠。
範例應用程式使用環境變數組態提供者來設定連接埠。 連接埠是在 launchSettings.json
檔案中設定,並透過環境變數傳遞至設定提供者。 您也必須將伺服器設定為在管理連接埠上接聽要求。
若要使用範例應用程式來示範管理連接埠設定,請在 Properties
資料夾中建立 launchSettings.json
檔案。
範例應用程式中的下列 Properties/launchSettings.json
檔案未包括在範例應用程式的專案檔中,而且必須手動予以建立:
{
"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 登錄健康狀態檢查服務。 在 Startup.Configure
中呼叫 MapHealthChecks
,以建立健康情況檢查端點。
在範例應用程式中,對 Startup.Configure
中端點的 RequireHost
呼叫指定設定管理連接埠:
endpoints.MapHealthChecks("/health")
.RequireHost($"*:{Configuration["ManagementPort"]}");
在範例應用程式的 Startup.Configure
中,建立端點。 在下列範例程式碼中:
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
});
}
備註
您可以在程式碼中明確設定管理連接埠,以避免在範例應用程式中建立 launchSettings.json
檔案。 在 HostBuilder 建立所在的 Program.cs
中,新增 ListenAnyIP 呼叫,並提供應用程式的管理連接埠端點。 在 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");
});
若要使用範例應用程式執行管理連接埠組態案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario port
若要發佈健康狀態檢查作為程式庫:
寫入健康狀態檢查,將 IHealthCheck 介面當做獨立類別來實作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項來存取組態資料。
在 CheckHealthAsync
的健全狀況檢查邏輯中:
data1
和 data2
用於此方法,以執行探查的健康情況檢查邏輯。AccessViolationException
。發生 AccessViolationException 時,會使用 HealthCheckResult 來傳回 FailureStatus,以允許使用者設定健康情況檢查失敗狀態。
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);
}
}
}
}
使用取用應用程式在其 Startup.Configure
方法中呼叫的參數,來寫入延伸模組。 在下列範例中,假設健康狀態檢查方法簽章如下:
ExampleHealthCheck(string, string, int )
上述簽章指出 ExampleHealthCheck
需要額外的資料,才能處理健康狀態檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態檢查時,用來建立健康狀態檢查執行個體。 在下列範例中,呼叫者會選擇性地指定:
name
)。 如果為 null
,則會使用 example_health_check
。data1
)。data2
)。 如果為 null
,則會使用 1
。null
。 如果為 null
,則會報告失敗狀態為 HealthStatus.Unhealthy。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));
}
}
當 IHealthCheckPublisher 新增至服務容器時,健康狀態檢查系統會定期執行健康狀態檢查,並呼叫 PublishAsync
傳回結果。 這對推送型健康狀態監控系統案例很有用,其預期每個處理序會定期呼叫監控系統來判斷健康狀態。
IHealthCheckPublisher 介面有單一方法:
Task PublishAsync(HealthReport report, CancellationToken cancellationToken);
HealthCheckPublisherOptions 可讓您設定:
null
(預設),則健康情況檢查發行者服務會執行所有已登錄的健康情況檢查。 若要執行一部分的健康狀態檢查,請提供可篩選該組檢查的函式。 每個期間都會評估該述詞。在範例應用程式中,ReadinessPublisher
是一個 IHealthCheckPublisher 實作。 在下列記錄層級,會記錄每個檢查的健康情況檢查狀態:
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;
}
}
在範例應用程式的 LivenessProbeStartup
範例中,StartupHostedService
整備檢查具有 2 秒的啟動延遲,且每 30 秒會執行一次檢查。 為了啟用 IHealthCheckPublisher 實作,此範例會在相依性插入 (DI) 容器中將 ReadinessPublisher
註冊為單一服務:
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>();
備註
AspNetCore.Diagnostics.HealthChecks
包括數個系統的發行者,包括 Application Insights。
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
使用 MapWhen 來有條件地將健康情況檢查端點的要求管線分支。
在下列範例中,如果接收到 api/HealthCheck
端點的 GET 要求,則 MapWhen
會對要求管線進行分支處理,以啟用健康情況檢查中介軟體:
app.MapWhen(
context => context.Request.Method == HttpMethod.Get.Method &&
context.Request.Path.StartsWith("/api/HealthCheck"),
builder => builder.UseHealthChecks());
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
如需詳細資訊,請參閱 ASP.NET Core 中介軟體。
ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應用程式基礎結構元件的健康情況。
應用程式會將健康狀態檢查公開為 HTTP 端點。 您可以針對各種即時監控案例來設定健康情況檢查端點:
檢視或下載範例程式碼 \(英文\) (如何下載)
範例應用程式包括本文中所述的案例範例。 若要在指定的案例中執行範例應用程式,請在命令殼層中使用來自專案資料夾的 dotnet run 命令。 如需如何使用範例應用程式的詳細資料,請參閱範例應用程式的 README.md
檔案和本文中的案例描述。
健康情況檢查通常會與外部監控服務或容器協調器搭配使用,來檢查應用程式的狀態。 將健康狀態檢查新增至應用程式之前,請決定要使用的監控系統。 監控系統會指定要建立哪些健康狀態檢查類型,以及如何設定其端點。
ASP.NET Core 應用程式會隱含參考 Microsoft.AspNetCore.Diagnostics.HealthChecks
套件。 若要使用 Entity Framework Core 來執行健康情況檢查,請新增 Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
套件的套件參考。
範例應用程式提供啟動程式碼,來示範數個案例的健康狀態檢查。 資料庫探查案例使用 AspNetCore.Diagnostics.HealthChecks
來檢查資料庫連線的健康情況。 DbContext 探查案例使用 EF CoreDbContext
來檢查資料庫。 為了探索資料庫案例,範例應用程式會:
appsettings.json
檔案中提供其連接字串。備註
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
另一個健康狀態檢查案例示範如何將健康狀態檢查篩選至管理連接埠。 範例應用程式需要您建立 Properties/launchSettings.json
檔案,而此檔案包括管理 URL 和管理連接埠。 如需詳細資訊,請參閱依連接埠篩選一節。
對於許多應用程式,報告應用程式是否可處理要求的基本健康狀態探查組態 (「活躍度」),便足以探索應用程式的狀態。
基本設定會登錄健康情況檢查服務,並呼叫健康情況檢查中介軟體以在具有健康情況回應的 URL 端點做出回應。 預設並未登錄特定健康狀態檢查來測試任何特定相依性或子系統。 如果應用程式可以在健康情況端點 URL 做出回應,則視為狀況良好。 預設回應寫入器會將狀態 (HealthStatus) 以純文字回應形式回寫至用戶端,指出 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy 狀態。
在 Startup.ConfigureServices
中,使用 AddHealthChecks 登錄健康狀態檢查服務。 在 Startup.Configure
中呼叫 MapHealthChecks
,以建立健康情況檢查端點。
在範例應用程式中,是在 /health
(BasicStartup.cs
) 建立健康情況檢查端點:
public class BasicStartup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
}
}
若要使用範例應用程式執行基本組態案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario basic
Docker 提供內建 HEALTHCHECK
指示詞,可用來檢查使用基本健康狀態檢查組態的應用程式狀態:
HEALTHCHECK CMD curl --fail http://localhost:5000/health || exit
健康狀態檢查是藉由實作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態為 Healthy
、Degraded
或 Unhealthy
的 HealthCheckResult。 結果會寫成具有可設定狀態碼的純文字回應 (健康狀態檢查選項一節中將說明如何進行組態)。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。
下列 ExampleHealthCheck
類別示範健康情況檢查的配置。 健康情況檢查邏輯放在 CheckHealthAsync
方法中。 下列範例會將虛擬變數 healthCheckResultHealthy
設定為 true
。 如果 healthCheckResultHealthy
的值設定為 false
,則會傳回 HealthCheckResult.Unhealthy
狀態。
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."));
}
}
在 Startup.ConfigureServices
中使用 AddCheck,以將 ExampleHealthCheck
類型新增至健康情況檢查服務:
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>("example_health_check");
下列範例中所顯示的 AddCheck 多載會設定在健康狀態檢查報告失敗時所要報告的失敗狀態 (HealthStatus)。 如果將失敗狀態設定為 null
(預設),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態檢查實作採用此設定,則當健康狀態檢查失敗時,應用程式就會強制程式庫指出失敗狀態。
您可以使用「標籤」來篩選健康狀態檢查 (篩選健康狀態檢查一節中將進一步說明)。
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>(
"example_health_check",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" });
AddCheck 也可以執行匿名函式。 在下列範例中,健康狀態檢查名稱指定為 Example
,且檢查一律會傳回狀況良好狀態:
services.AddHealthChecks()
.AddCheck("Example", () =>
HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });
呼叫 AddTypeActivatedCheck,以將引數傳遞至健康情況檢查實作。 在下列範例中,TestHealthCheckWithArgs
接受在呼叫 CheckHealthAsync 時使用整數和字串:
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)
{
...
}
}
使用傳遞至實作的整數和字串來呼叫 AddTypeActivatedCheck
,以登錄 TestHealthCheckWithArgs
:
services.AddHealthChecks()
.AddTypeActivatedCheck<TestHealthCheckWithArgs>(
"test",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" },
args: new object[] { 5, "string" });
在 Startup.Configure
中,使用端點 URL 或相對路徑以在端點建立器上呼叫 MapHealthChecks
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
});
呼叫 RequireHost
,以將一或多個允許的主機指定給健康情況檢查端點。 主機應該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機。
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireHost("www.contoso.com:5001");
});
如需詳細資訊,請參閱依連接埠篩選一節。
呼叫 RequireAuthorization
,以在健康情況檢查要求端點上執行授權中介軟體。 RequireAuthorization
多載接受一或多個授權原則。 如果未提供原則,則會使用預設授權原則。
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health").RequireAuthorization();
});
雖然從瀏覽器手動執行健康情況檢查不是常見使用案例,但是您可以在健康情況檢查端點上呼叫 RequireCors
,以啟用 CORS 中介軟體。 RequireCors
多載接受 CORS 原則建立器委派 (CorsPolicyBuilder
) 或原則名稱。 如果未提供原則,則會使用預設 CORS 原則。 如需詳細資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。
HealthCheckOptions 讓您有機會自訂健康狀態檢查行為:
根據預設,健康情況檢查中介軟體會執行所有已登錄的健康情況檢查。 若要執行健康狀態檢查子集,請對 Predicate 選項提供傳回布林值的函式。 在下列範例中,會依函式條件陳述式中的標籤 (bar_tag
) 篩選出 Bar
健康狀態檢查。只有在健康狀態檢查的 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 才能執行:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("foo_tag") ||
check.Tags.Contains("baz_tag")
});
});
您可以使用 ResultStatusCodes 來自訂健康狀態與 HTTP 狀態碼的對應。 下列 StatusCodes 指派是中介軟體所使用的預設值。 請變更狀態碼值以符合您的需求。
在 Startup.Configure
中:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
});
AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標頭新增至探查回應,以防止回應快取。 如果值為 false
(預設),則中介軟體會設定或覆寫 Cache-Control
、Expires
和 Pragma
標頭,以防止回應快取。 如果值為 true
,則中介軟體不會修改回應的快取標頭。
在 Startup.Configure
中:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
AllowCachingResponses = true
});
});
在 Startup.Configure
中,將 HealthCheckOptions.ResponseWriter 選項設定為撰寫回應的委派:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResponseWriter = WriteResponse
});
});
預設委派會使用字串值 HealthReport.Status
寫入基本純文字回應。 下列自訂委派會輸出自訂 JSON 回應。
範例應用程式中的第一個範例示範如何使用 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);
}
}
第二個範例示範如何使用 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));
}
在範例應用程式中,註解化 CustomWriterStartup.cs
中的 SYSTEM_TEXT_JSON
前置處理器指示詞,以啟用 WriteResponse
的 Newtonsoft.Json
版本。
健康情況檢查 API 未提供複雜 JSON 傳回格式的內建支援,因為此格式是您所選擇的監控系統所特有。 視需要,自訂上述範例中的回應。 如需使用 System.Text.Json
進行 JSON 序列化的詳細資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。
健康狀態檢查可指定資料庫查詢以布林測試方式來執行,藉此指出資料庫是否正常回應。
範例應用程式使用 AspNetCore.Diagnostics.HealthChecks
(一種適用於 ASP.NET Core 應用程式的健康情況檢查程式庫),以在 SQL Server 資料庫上執行健康情況檢查。 AspNetCore.Diagnostics.HealthChecks
會對資料庫執行 SELECT 1
查詢,以確認資料庫連線狀況良好。
警告
使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風險。 在大部分情況下,不需要執行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發現有必要執行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1
。
包括 AspNetCore.HealthChecks.SqlServer
的套件參考。
在範例應用程式的 appsettings.json
檔案中,提供有效的資料庫連接字串。 應用程式使用名為 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 登錄健康狀態檢查服務。 範例應用程式會使用資料庫連接字串 (DbHealthStartup.cs
) 來呼叫 AddSqlServer
方法:
services.AddHealthChecks()
.AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
}
若要使用範例應用程式執行資料庫探查案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario db
備註
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
DbContext
檢查會確認應用程式是否可以與針對 EF CoreDbContext
所設定的資料庫通訊。 應用程式支援 DbContext
檢查:
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
的套件參考。AddDbContextCheck<TContext>
會登錄 DbContext
的健康狀態檢查。 DbContext
會以 TContext
形式提供給方法。 多載可用來設定失敗狀態、標籤和自訂測試查詢。
預設情況:
DbContextHealthCheck
會呼叫 EF Core 的 CanConnectAsync
方法。 您可以自訂使用 AddDbContextCheck
方法多載檢查健康狀態時所要執行的作業。TContext
類型的名稱。在範例應用程式中,會將 AppDbContext
提供給 AddDbContextCheck
,並在 Startup.ConfigureServices
中登錄為服務 (DbContextHealthStartup.cs
):
services.AddHealthChecks()
.AddDbContextCheck<AppDbContext>();
services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(
Configuration["ConnectionStrings:DefaultConnection"]);
});
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health");
}
若要使用範例應用程式來執行 DbContext
探查案例,請確認 SQL Server 執行個體中沒有連接字串所指定的資料庫。 如果資料庫存在,請予以刪除。
在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario dbcontext
在應用程式執行之後,對瀏覽器中的 /health
端點提出要求來檢查健康狀態。 資料庫和 AppDbContext
不存在,因此應用程式會提供下列回應:
Unhealthy
觸發範例應用程式以建立資料庫。 對 /createdatabase
提出要求。 應用程式會回應:
Creating the database...
Done!
Navigate to /health to see the health status.
對 /health
端點提出要求。 資料庫和內容存在,因此應用程式會回應:
Healthy
觸發範例應用程式以刪除資料庫。 對 /deletedatabase
提出要求。 應用程式會回應:
Deleting the database...
Done!
Navigate to /health to see the health status.
對 /health
端點提出要求。 應用程式會提供狀況不良回應:
Unhealthy
在某些裝載案例中,會使用一組健康情況檢查來區分兩個應用程式狀態:
請考慮下列範例:應用程式在準備好處理要求之前必須下載大型設定檔。 如果初始下載失敗,則我們不想要重新啟動應用程式,因為應用程式可以重試下載檔案數次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執行其他檢查。 我們也想要防止在設定檔下載成功之前將要求傳送至應用程式。 除非下載成功,而且應用程式準備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」狀態。
範例應用程式包含健康狀態檢查,會在託管服務中長時間執行的啟動工作完成時回報。 StartupHostedServiceHealthCheck
會公開 StartupTaskCompleted
屬性,而裝載的服務可以在其長時間執行的工作完成時,將此屬性設定為 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."));
}
}
裝載的服務 (Services/StartupHostedService
) 會啟動長時間執行的背景工作。 工作完成時,StartupHostedServiceHealthCheck.StartupTaskCompleted
會設定為 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()
{
}
}
健康狀態檢查是 Startup.ConfigureServices
中使用 AddCheck 隨託管服務一起登錄。 因為所裝載服務必須在健康情況檢查上設定此屬性,所以也會在服務容器中登錄健康情況檢查 (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>();
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
。 在範例應用程式中,是在下列位置建立健康情況檢查端點:
/health/ready
用於整備檢查。 整備度檢查使用 ready
標籤來篩選健康狀態檢查。/health/live
用於活躍度檢查。 活躍度檢查是在 HealthCheckOptions.Predicate
中傳回 false
來篩選出 StartupHostedServiceHealthCheck
(如需詳細資訊,請參閱篩選健康情況檢查)在下列範例程式碼中:
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
});
}
若要使用範例應用程式執行整備度/活躍度組態案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario liveness
在瀏覽器中,瀏覽 /health/ready
數次,直到經過 15 秒。 健康狀態檢查報告前 15 秒為 Unhealthy
。 15 秒之後,端點會報告 Healthy
,以反映託管服務長時間執行的工作已完成。
此範例也會建立一個以兩秒延遲執行第一次整備檢查的「健康情況檢查發行者」(IHealthCheckPublisher 實作)。 如需詳細資訊,請參閱健康狀態檢查發行者一節。
使用個別的整備度與活躍度檢查在 Kubernetes 之類的環境中很有用。 在 Kubernetes 中,應用程式可能需要先執行耗時的啟動工作,才能接受要求 (例如基礎資料庫可用性測試)。 使用個別的檢查可讓協調器區分應用程式是否為正常運作但尚未準備好,或應用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設定活躍度與整備度探查)。
下列範例示範 Kubernetes 整備度探查組態:
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
範例應用程式示範透過自訂回應寫入器的記憶體健康狀態檢查。
如果應用程式使用超過指定的記憶體閾值 (在範例應用程式中為 1 GB),MemoryHealthCheck
會報告降級的狀態。 HealthCheckResult 包括應用程式的記憶體回收行程 (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 登錄健康狀態檢查服務。 MemoryHealthCheck
會登錄為服務,而不是將健康狀態檢查傳遞至 AddCheck 以啟用檢查。 所有 IHealthCheck 登錄的服務都可供健康狀態檢查服務和中介軟體使用。 建議將健康狀態檢查服務登錄為單一服務。
在範例應用程式的 CustomWriterStartup.cs
中:
services.AddHealthChecks()
.AddMemoryHealthCheck("memory");
健康情況檢查端點的建立方式是在 Startup.Configure
中呼叫 MapHealthChecks
。 當健康狀態檢查執行時,會將 WriteResponse
委派提供給 ResponseWriter 屬性以輸出自訂 JSON 回應:
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
ResponseWriter = WriteResponse
});
}
WriteResponse
委派會將 CompositeHealthCheckResult
格式化為 JSON 物件,並產生健康情況檢查回應的 JSON 輸出。 如需詳細資訊,請參閱自訂輸出小節。
若要使用範例應用程式透過自訂回應寫入器輸出執行計量型探查,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario writer
備註
AspNetCore.Diagnostics.HealthChecks
包括計量型健康情況檢查案例,包括磁碟儲存體和最大值活躍度檢查。
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
使用 URL 模式以在 MapHealthChecks
上呼叫 RequireHost
,而此模式指定連接埠來限制針對所指定連接埠的健康情況檢查要求。 此方式通常用於容器環境,以公開監控服務的連接埠。
範例應用程式使用環境變數組態提供者來設定連接埠。 連接埠是在 launchSettings.json
檔案中設定,並透過環境變數傳遞至設定提供者。 您也必須將伺服器設定為在管理連接埠上接聽要求。
若要使用範例應用程式來示範管理連接埠設定,請在 Properties
資料夾中建立 launchSettings.json
檔案。
範例應用程式中的下列 Properties/launchSettings.json
檔案未包括在範例應用程式的專案檔中,而且必須手動予以建立:
{
"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 登錄健康狀態檢查服務。 在 Startup.Configure
中呼叫 MapHealthChecks
,以建立健康情況檢查端點。
在範例應用程式中,對 Startup.Configure
中端點的 RequireHost
呼叫指定設定管理連接埠:
endpoints.MapHealthChecks("/health")
.RequireHost($"*:{Configuration["ManagementPort"]}");
在範例應用程式的 Startup.Configure
中,建立端點。 在下列範例程式碼中:
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
});
}
備註
您可以在程式碼中明確設定管理連接埠,以避免在範例應用程式中建立 launchSettings.json
檔案。 在 HostBuilder 建立所在的 Program.cs
中,新增 ListenAnyIP 呼叫,並提供應用程式的管理連接埠端點。 在 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");
});
若要使用範例應用程式執行管理連接埠組態案例,請在命令殼層中執行來自專案資料夾的下列命令:
dotnet run --scenario port
若要發佈健康狀態檢查作為程式庫:
寫入健康狀態檢查,將 IHealthCheck 介面當做獨立類別來實作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項來存取組態資料。
在 CheckHealthAsync
的健全狀況檢查邏輯中:
data1
和 data2
用於此方法,以執行探查的健康情況檢查邏輯。AccessViolationException
。發生 AccessViolationException 時,會使用 HealthCheckResult 來傳回 FailureStatus,以允許使用者設定健康情況檢查失敗狀態。
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);
}
}
}
}
使用取用應用程式在其 Startup.Configure
方法中呼叫的參數,來寫入延伸模組。 在下列範例中,假設健康狀態檢查方法簽章如下:
ExampleHealthCheck(string, string, int )
上述簽章指出 ExampleHealthCheck
需要額外的資料,才能處理健康狀態檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態檢查時,用來建立健康狀態檢查執行個體。 在下列範例中,呼叫者會選擇性地指定:
name
)。 如果為 null
,則會使用 example_health_check
。data1
)。data2
)。 如果為 null
,則會使用 1
。null
。 如果為 null
,則會報告失敗狀態為 HealthStatus.Unhealthy。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));
}
}
當 IHealthCheckPublisher 新增至服務容器時,健康狀態檢查系統會定期執行健康狀態檢查,並呼叫 PublishAsync
傳回結果。 這對推送型健康狀態監控系統案例很有用,其預期每個處理序會定期呼叫監控系統來判斷健康狀態。
IHealthCheckPublisher 介面有單一方法:
Task PublishAsync(HealthReport report, CancellationToken cancellationToken);
HealthCheckPublisherOptions 可讓您設定:
null
(預設),則健康情況檢查發行者服務會執行所有已登錄的健康情況檢查。 若要執行一部分的健康狀態檢查,請提供可篩選該組檢查的函式。 每個期間都會評估該述詞。在範例應用程式中,ReadinessPublisher
是一個 IHealthCheckPublisher 實作。 在下列記錄層級,會記錄每個檢查的健康情況檢查狀態:
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;
}
}
在範例應用程式的 LivenessProbeStartup
範例中,StartupHostedService
整備檢查具有 2 秒的啟動延遲,且每 30 秒會執行一次檢查。 為了啟用 IHealthCheckPublisher 實作,此範例會在相依性插入 (DI) 容器中將 ReadinessPublisher
註冊為單一服務:
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>();
備註
AspNetCore.Diagnostics.HealthChecks
包括數個系統的發行者,包括 Application Insights。
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
使用 MapWhen 來有條件地將健康情況檢查端點的要求管線分支。
在下列範例中,如果接收到 api/HealthCheck
端點的 GET 要求,則 MapWhen
會對要求管線進行分支處理,以啟用健康情況檢查中介軟體:
app.MapWhen(
context => context.Request.Method == HttpMethod.Get.Method &&
context.Request.Path.StartsWith("/api/HealthCheck"),
builder => builder.UseHealthChecks());
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
如需詳細資訊,請參閱 ASP.NET Core 中介軟體。
ASP.NET Core 提供健康情況檢查中介軟體和程式庫,用來報告應用程式基礎結構元件的健康情況。
應用程式會將健康狀態檢查公開為 HTTP 端點。 您可以針對各種即時監控案例來設定健康情況檢查端點:
健康情況檢查通常會與外部監控服務或容器協調器搭配使用,來檢查應用程式的狀態。 將健康狀態檢查新增至應用程式之前,請決定要使用的監控系統。 監控系統會指定要建立哪些健康狀態檢查類型,以及如何設定其端點。
對於許多應用程式,報告應用程式是否可處理要求的基本健康狀態探查組態 (「活躍度」),便足以探索應用程式的狀態。
基本設定會登錄健康情況檢查服務,並呼叫健康情況檢查中介軟體以在具有健康情況回應的 URL 端點做出回應。 預設並未登錄特定健康狀態檢查來測試任何特定相依性或子系統。 如果應用程式可以在健康情況端點 URL 做出回應,則視為狀況良好。 預設回應寫入器會將 HealthStatus 以純文字回應形式寫入至用戶端。 HealthStatus
是 HealthStatus.Healthy、HealthStatus.Degraded 或 HealthStatus.Unhealthy。
在 Program.cs
中,使用 AddHealthChecks 登錄健康狀態檢查服務。 呼叫 MapHealthChecks 來建立健康情況檢查端點。
下列範例會在 /healthz
建立健康情況檢查端點:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/healthz");
app.Run();
Docker 提供內建 HEALTHCHECK
指示詞,可用來檢查使用基本健康狀態檢查組態的應用程式狀態:
HEALTHCHECK CMD curl --fail http://localhost:5000/healthz || exit
上述範例會使用 curl
,以在 /healthz
針對健康情況檢查端點提出 HTTP 要求。 curl
未包括在 .NET Linux 容器映像中,但可以在 Dockerfile 中安裝必要套件來進行新增。 根據 Alpine Linux 來使用映像的容器可以使用所包括的 wget
來取代 curl
。
健康狀態檢查是藉由實作 IHealthCheck 介面來建立。 CheckHealthAsync 方法會傳回指出狀態為 Healthy
、Degraded
或 Unhealthy
的 HealthCheckResult。 結果會寫成具有可設定狀態碼的純文字回應。 健康情況檢查選項小節中會描述設定。 HealthCheckResult 也可以傳回選擇性索引鍵/值組。
下列範例示範健康情況檢查的配置:
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 方法中。 上述範例會將虛擬變數 isHealthy
設定為 true
。 如果 isHealthy
的值設定為 false
,則會傳回 HealthCheckRegistration.FailureStatus 狀態。
如果 CheckHealthAsync 在檢查期間擲回例外狀況,則會傳回其 HealthReportEntry.Status 設定為 FailureStatus 的新 HealthReportEntry。 此狀態是由 AddCheck 所定義 (請參閱登錄健康情況檢查服務一節),並包括造成檢查失敗的內部例外狀況。 Description 會設定為例外狀況的訊息。
若要登錄健康情況檢查服務,請在 Program.cs
中呼叫 AddCheck:
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>("Sample");
下列範例中所顯示的 AddCheck 多載會設定在健康狀態檢查報告失敗時所要報告的失敗狀態 (HealthStatus)。 如果將失敗狀態設定為 null
(預設),則會報告 HealthStatus.Unhealthy。 此多載對程式庫作者很有用。若健康狀態檢查實作採用此設定,則當健康狀態檢查失敗時,應用程式就會強制程式庫指出失敗狀態。
「標記」可以用來篩選健康情況檢查。 標記會在篩選健康情況檢查小節中予以描述。
builder.Services.AddHealthChecks()
.AddCheck<SampleHealthCheck>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" });
AddCheck 也可以執行匿名函式。 在下列範例中,健康情況檢查一律會傳回狀況良好結果:
builder.Services.AddHealthChecks()
.AddCheck("Sample", () => HealthCheckResult.Healthy("A healthy result."));
呼叫 AddTypeActivatedCheck,以將引數傳遞至健康情況檢查實作。 在下列範例中,啟用類型的健康情況檢查會在其建構函式中接受整數和字串:
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."));
}
}
若要登錄上述健康情況檢查,請使用傳遞為引數的整數和字串來呼叫 AddTypeActivatedCheck
:
builder.Services.AddHealthChecks()
.AddTypeActivatedCheck<SampleHealthCheckWithArgs>(
"Sample",
failureStatus: HealthStatus.Degraded,
tags: new[] { "sample" },
args: new object[] { 1, "Arg" });
在 Program.cs
中,使用端點 URL 或相對路徑以在端點建立器上呼叫 MapHealthChecks
:
app.MapHealthChecks("/healthz");
呼叫 RequireHost
,以將一或多個允許的主機指定給健康情況檢查端點。 主機應該是 Unicode,而不是 punycode,而且可能會包括連接埠。 如果未提供集合,則會接受任何主機:
app.MapHealthChecks("/healthz")
.RequireHost("www.contoso.com:5001");
若要限制健康情況檢查端點只在特定連接埠上回應,請在 RequireHost
呼叫中指定連接埠。 此方式通常用於容器環境,以公開監控服務的連接埠:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001");
警告
依賴於主機標頭的 API (例如 HttpRequest.Host 和 RequireHost) 可能會受到用戶端的詐騙。
若要防止主機和連接埠詐騙,請使用下列其中一種方式:
若要防止未經授權的用戶端詐騙連接埠,請呼叫 RequireAuthorization:
app.MapHealthChecks("/healthz")
.RequireHost("*:5001")
.RequireAuthorization();
如需詳細資訊,請參閱具有 RequireHost 之路由中的主機比對。
呼叫 RequireAuthorization,以在健康情況檢查要求端點上執行授權中介軟體。 RequireAuthorization
多載接受一或多個授權原則。 如果未提供原則,則會使用預設授權原則:
app.MapHealthChecks("/healthz")
.RequireAuthorization();
雖然從瀏覽器手動執行健康情況檢查不是常見案例,但是您可以在健康情況檢查端點上呼叫 RequireCors
,以啟用 CORS 中介軟體。 RequireCors
多載接受 CORS 原則建立器委派 (CorsPolicyBuilder
) 或原則名稱。 如需詳細資訊,請參閱在 ASP.NET Core 中啟用跨原始來源要求 (CORS)。
HealthCheckOptions 讓您有機會自訂健康狀態檢查行為:
根據預設,健康情況檢查中介軟體會執行所有已登錄的健康情況檢查。 若要執行健康狀態檢查子集,請對 Predicate 選項提供傳回布林值的函式。
下列範例會篩選健康情況檢查,以只執行已標記 sample
的檢查:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("sample")
});
您可以使用 ResultStatusCodes 來自訂健康狀態與 HTTP 狀態碼的對應。 下列 StatusCodes 指派是中介軟體所使用的預設值。 變更狀態碼值,以符合您的需求:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable
}
});
AllowCachingResponses 會控制健康情況檢查中介軟體是否將 HTTP 標頭新增至探查回應,以防止回應快取。 如果值為 false
(預設),則中介軟體會設定或覆寫 Cache-Control
、Expires
和 Pragma
標頭,以防止回應快取。 如果值為 true
,則中介軟體不會修改回應的快取標頭:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
AllowCachingResponses = true
});
若要自訂健康情況檢查報告的輸出,請將 HealthCheckOptions.ResponseWriter 屬性設定為可寫入回應的委派:
app.MapHealthChecks("/healthz", new HealthCheckOptions
{
ResponseWriter = WriteResponse
});
預設委派會使用字串值 HealthReport.Status
寫入基本純文字回應。 下列自訂委派會使用 System.Text.Json來輸出自訂 JSON 回應:
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 傳回格式的內建支援,因為此格式是您所選擇的監控系統所特有。 視需要,自訂上述範例中的回應。 如需使用 System.Text.Json
進行 JSON 序列化的詳細資訊,請參閱 如何在 .NET 中序列化和還原序列化 JSON。
健康狀態檢查可指定資料庫查詢以布林測試方式來執行,藉此指出資料庫是否正常回應。
AspNetCore.Diagnostics.HealthChecks
,一種適用於 ASP.NET Core 應用程式的健康情況檢查程式庫,包括針對 SQL Server 資料庫所執行的健康情況檢查。 AspNetCore.Diagnostics.HealthChecks
會對資料庫執行 SELECT 1
查詢,以確認資料庫連線狀況良好。
警告
使用查詢檢查資料庫連線時,請選擇快速傳回的查詢。 查詢方法具有多載資料庫而降低其效能的風險。 在大部分情況下,不需要執行測試查詢。 只要成功建立資料庫連線就已足夠。 如果您發現有必要執行查詢,請選擇簡單的 SELECT 查詢,例如 SELECT 1
。
若要使用此 SQL Server 健康情況檢查,請包括 AspNetCore.HealthChecks.SqlServer
NuGet 套件的套件參考。 下列範例會登錄 SQL Server 健康情況檢查:
builder.Services.AddHealthChecks()
.AddSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection"));
備註
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
DbContext
檢查會確認應用程式是否可以與針對 EF CoreDbContext
所設定的資料庫通訊。 應用程式支援 DbContext
檢查:
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
NuGet 套件的套件參考。AddDbContextCheck 會登錄 DbContext 的健康狀態檢查。 DbContext
會以 TContext
形式提供給方法。 多載可用來設定失敗狀態、標籤和自訂測試查詢。
預設情況:
DbContextHealthCheck
會呼叫 EF Core 的 CanConnectAsync
方法。 您可以自訂使用 AddDbContextCheck
方法多載檢查健康狀態時所要執行的作業。TContext
類型的名稱。下列範例會登錄 DbContext
和相關聯的 DbContextHealthCheck
:
builder.Services.AddDbContext<SampleDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddHealthChecks()
.AddDbContextCheck<SampleDbContext>();
在某些裝載案例中,會使用一組健康情況檢查來區分兩個應用程式狀態:
請考慮下列範例:應用程式在準備好處理要求之前必須下載大型設定檔。 如果初始下載失敗,則我們不想要重新啟動應用程式,因為應用程式可以重試下載檔案數次。 我們使用「活躍度探查」來描述處理序的活躍度,而不會執行其他檢查。 我們也想要防止在設定檔下載成功之前將要求傳送至應用程式。 除非下載成功,而且應用程式準備好接收要求,否則我們會使用「整備度探查」來指出「尚未就緒」狀態。
下列背景工作會模擬大約需要 15 秒的啟動處理序。 完成後,工作會將 StartupHealthCheck.StartupCompleted
屬性設定為 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
會報告長時間執行的啟動工作完成,並公開背景服務所設定的 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."));
}
}
健康狀態檢查是 Program.cs
中使用 AddCheck 隨託管服務一起登錄。 因為所裝載服務必須在健康情況檢查上設定此屬性,所以也會在服務容器中將健康情況檢查登錄為單一資料庫:
builder.Services.AddHostedService<StartupBackgroundService>();
builder.Services.AddSingleton<StartupHealthCheck>();
builder.Services.AddHealthChecks()
.AddCheck<StartupHealthCheck>(
"Startup",
tags: new[] { "ready" });
若要建立兩個不同的健康情況檢查端點,請呼叫 MapHealthChecks
兩次:
app.MapHealthChecks("/healthz/ready", new HealthCheckOptions
{
Predicate = healthCheck => healthCheck.Tags.Contains("ready")
});
app.MapHealthChecks("/healthz/live", new HealthCheckOptions
{
Predicate = _ => false
});
上述範例會建立下列健康情況檢查端點:
/healthz/ready
用於整備檢查。 整備檢查會將健康情況檢查篩選為已標記 ready
的檢查。/healthz/live
用於活躍度檢查。 活躍度檢查會在 HealthCheckOptions.Predicate 委派中傳回 false
,以篩選出所有健康情況檢查。 如需篩選健康情況檢查的詳細資訊,請參閱本文中的篩選健康情況檢查。啟動工作完成之前,/healthz/ready
端點會回報 Unhealthy
狀態。 啟動工作完成之後,此端點會回報 Healthy
狀態。 /healthz/live
端點會排除所有檢查,並將所有呼叫的狀態都回報為 Healthy
。
使用個別的整備度與活躍度檢查在 Kubernetes 之類的環境中很有用。 在 Kubernetes 中,應用程式可能需要先執行耗時的啟動工作,才能接受要求 (例如基礎資料庫可用性測試)。 使用個別的檢查可讓協調器區分應用程式是否為正常運作但尚未準備好,或應用程式是否無法啟動。 如需 Kubernetes 中整備度與活躍度探查的詳細資訊,請參閱 Kubernetes 文件中的 Configure Liveness and Readiness Probes (設定活躍度與整備度探查)。
下列範例示範 Kubernetes 整備度探查組態:
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
若要發佈健康狀態檢查作為程式庫:
寫入健康狀態檢查,將 IHealthCheck 介面當做獨立類別來實作。 此類別可能依賴相依性插入 (DI)、類型啟用和具名選項來存取組態資料。
使用取用應用程式在其 Program.cs
方法中呼叫的參數,來寫入延伸模組。 請考慮下列範例健康情況檢查,而此檢查接受 arg1
和 arg2
作為建構函式參數:
public SampleHealthCheckWithArgs(int arg1, string arg2)
=> (_arg1, _arg2) = (arg1, arg2);
上述簽章指出健康情況檢查需要自訂資料,才能處理健康情況檢查探查邏輯。 此資料會提供給委派,以在使用延伸模組登錄健康狀態檢查時,用來建立健康狀態檢查執行個體。 在下列範例中,呼叫端會指定:
arg1
:健康情況檢查的整數資料點。arg2
:健康情況檢查的字串引數。name
:選用的健康情況檢查名稱。 如果 null
,則會使用預設值。failureStatus
:選用的 HealthStatus,其回報失敗狀態。 如果為 null
,則會使用 HealthStatus.Unhealthy。tags
:標記的選用 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));
}
}
當 IHealthCheckPublisher 新增至服務容器時,健康狀態檢查系統會定期執行健康狀態檢查,並呼叫 PublishAsync 傳回結果。 此處理序適用於推送型健康情況監控系統案例,而此案例預期每個處理序都會定期呼叫監控系統來判斷健康情況。
HealthCheckPublisherOptions 可讓您設定:
null
(預設),則健康情況檢查發行者服務會執行所有已登錄的健康情況檢查。 若要執行一部分的健康狀態檢查,請提供可篩選該組檢查的函式。 每個期間都會評估該述詞。下列範例示範健康情況發行者的配置:
public class SampleHealthCheckPublisher : IHealthCheckPublisher
{
public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
{
if (report.Status == HealthStatus.Healthy)
{
// ...
}
else
{
// ...
}
return Task.CompletedTask;
}
}
HealthCheckPublisherOptions 類別提供屬性來設定健康情況檢查發行者的行為。
下列範例會將健康情況檢查發行者登錄為單一資料庫,並設定 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
包括數個系統的發行者,包括 Application Insights。
Microsoft 不會維護或支援 AspNetCore.Diagnostics.HealthChecks
。
您可以使用相依性插入來取用健康情況檢查類別內特定 Type
的執行個體。 相依性插入適用於將選項或全域設定插入至健康情況檢查。 使用相依性插入「不」是設定健康情況檢查的常見案例。 通常,每個健康情況檢查都是專屬於實際測試,並且使用 IHealthChecksBuilder
擴充方法進行設定。
下列範例顯示可透過相依性插入來擷取設定物件的範例健康情況檢查:
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
和健康情況檢查需要新增至服務容器:
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" });
有兩種方式可讓呼叫端存取健康情況檢查:
使用 MapHealthChecks
優於 UseHealthChecks
的優點是能夠使用端點感知中介軟體 (例如授權),並更精細地控制比對原則。 使用 UseHealthChecks
優於 MapHealthChecks
的主要優點是確切控制中介軟體管線中執行健康情況檢查的位置。
null
或空白 PathString
。 允許在針對所指定連接埠所提出的任何要求上執行健康情況檢查。MapHealthChecks 允許:
備註
本文部分是透過人工智慧協助建立的。 發佈之前,請視需要進行作者檢閱並修訂內容。 請參閱 Microsoft Learn 中我們對 AI 產生的內容之使用原則。
事件
Power BI DataViz World Championships
2月14日 下午4時 - 3月31日 下午4時
4 次參賽機會,有機會贏得會議套裝行程,現場參與在拉斯維加斯舉行的總決賽
進一步了解