ASP.NET Core中的運行狀況檢查


由盧克·萊瑟姆和格倫Condron

ASP.NET Core提供了運行狀況檢查中間件和庫,用於報告應用程序基礎結構組件的運行狀況。

運行狀況檢查由應用程序公開為HTTP終結點。可以為各種實時監視方案配置運行狀況檢查端點:

容器協調程序和負載平衡器可以使用運行狀況探針來檢查應用程序的狀態。例如,容器協調器可以通過停止滾動部署或重新啟動容器來響應運行狀況檢查失敗。負載平衡器可能會通過將流量從發生故障的實例路由到運行狀況良好的實例來對運行狀況不佳的應用程序做出反應。
可以監視內存,磁盤和其他物理服務器資源的使用情況,以確保運行狀況良好。
運行狀況檢查可以測試應用程序的依賴項(例如數據庫和外部服務端點),以確認可用性和正常功能。
查看或下載示例代碼(如何下載)

該示例應用程序包括本主題中描述的方案的示例。要在給定場景下運行示例應用程序,請在命令外殼中使用項目文件夾中的dotnet run命令。請參閱示例應用程序的README.md文件和本主題中的方案說明,以獲取有關如何使用示例應用程序的詳細信息。

先決條件
健康檢查通常與外部監視服務或容器協調程序一起使用,以檢查應用程序的狀態。在向應用程序添加運行狀況檢查之前,請確定要使用的監視系統。監視系統指示要創建的健康檢查類型以及如何配置其終結點。

引用Microsoft.AspNetCore.App元包,或將包引用添加到Microsoft.AspNetCore.Diagnostics.HealthChecks包。

該示例應用程序提供了啟動代碼,以演示幾種情況下的運行狀況檢查。該數據庫探測情況檢查使用數據庫連接的健康AspNetCore.Diagnostics.HealthChecks。該的DbContext探頭場景檢查使用EF核心數據庫DbContext。要探索數據庫方案,示例應用程序:

創建一個數據庫,並在appsettings.json文件中提供其連接字符串。
在其項目文件中具有以下程序包引用:
AspNetCore.HealthChecks.SqlServer
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore
注意

Microsoft不維護或不支持AspNetCore.Diagnostics.HealthChecks。

另一個運行狀況檢查方案演示了如何將運行狀況檢查過濾到管理端口。該示例應用程序要求您創建一個包含管理URL和管理端口的Properties / launchSettings.json文件。有關更多信息,請參見按端口過濾部分。

基本健康探針
對於許多應用程序而言,報告應用程序是否可處理請求(活動)的基本運行狀況探測器配置足以發現應用程序的狀態。

基本配置注冊運行狀況檢查服務,並調用運行狀況檢查中間件以在URL終結點響應並帶有運行狀況響應。默認情況下,沒有注冊特定的運行狀況檢查來測試任何特定的依賴項或子系統。如果該應用能夠在運行狀況端點URL上響應,則該應用程序被視為運行狀況良好。默認響應編寫器將狀態(HealthStatus)作為純文本響應寫回到客戶端,指示HealthStatus.Healthy,HealthStatus.Degraded或HealthStatus.Unhealthy狀態。

在中使用AddHealthChecks注冊運行狀況檢查服務Startup.ConfigureServices。在的請求處理管道中使用UseHealthChecks添加用於Health Checks中間件的端點Startup.Configure。

在示例應用程序中,運行狀況檢查端點在/health(BasicStartup.cs)中創建:

C#

復制
public class BasicStartup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
}

public void Configure(IApplicationBuilder app)
{
app.UseHealthChecks("/health");
}
}
要使用示例應用程序運行基本配置方案,請在命令外殼程序的項目文件夾中執行以下命令:

.NET Core CLI

復制
dotnet run --scenario basic
Docker范例
Docker提供了一個內置HEALTHCHECK指令,可用於檢查使用基本運行狀況檢查配置的應用程序的狀態:


復制
HEALTHCHECK CMD curl --fail http://localhost:5000/health || exit
創建健康檢查
通過實現IHealthCheck接口來創建運行狀況檢查。該CheckHealthAsync方法返回一個HealthCheckResult指示健康Healthy,Degraded或Unhealthy。結果以帶有可配置狀態代碼的純文本響應形式寫入(“運行狀況檢查選項”部分中描述了配置)。HealthCheckResult還可以返回可選的鍵值對。

健康檢查示例
以下ExampleHealthCheck課程演示了健康檢查的布局。健康檢查邏輯放置在CheckHealthAsync方法中。以下示例將虛擬變量設置healthCheckResultHealthy為true。如果將的值healthCheckResultHealthy設置為false,則返回HealthCheckResult.Unhealthy狀態。

C#

復制
public class ExampleHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default(CancellationToken))
{
var healthCheckResultHealthy = true;

if (healthCheckResultHealthy)
{
return Task.FromResult(
HealthCheckResult.Healthy("The check indicates a healthy result."));
}

return Task.FromResult(
HealthCheckResult.Unhealthy("The check indicates an unhealthy result."));
}
}
注冊健康檢查服務
該ExampleHealthCheck類型Startup.ConfigureServices通過AddCheck添加到運行狀況檢查服務中:

C#

復制
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>("example_health_check");
以下示例中顯示的AddCheck重載將故障狀態(HealthStatus)設置為在運行狀況檢查報告失敗時報告。如果故障狀態設置為null(默認),則報告HealthStatus.Unhealthy。對於庫作者而言,此重載是一個有用的方案,如果運行狀況檢查實現接受該設置,則當運行狀況檢查失敗時,應用程序會強制執行庫指示庫指示的故障狀態。

標簽可用於過濾運行狀況檢查(在“ 過濾運行狀況檢查”部分中進一步介紹)。

C#

復制
services.AddHealthChecks()
.AddCheck<ExampleHealthCheck>(
"example_health_check",
failureStatus: HealthStatus.Degraded,
tags: new[] { "example" });
AddCheck也可以執行lambda函數。在以下Startup.ConfigureServices示例中,運行狀況檢查名稱指定為,Example並且該檢查始終返回狀況良好的狀態:

C#

復制
services.AddHealthChecks()
.AddCheck("Example", () =>
HealthCheckResult.Healthy("Example is OK!"), tags: new[] { "example" });
使用運行狀況檢查中間件
在中Startup.Configure,使用端點URL或相對路徑在處理管道中調用UseHealthChecks:

C#

復制
app.UseHealthChecks("/health");
如果運行狀況檢查應偵聽特定端口,請使用UseHealthChecks的重載來設置端口(在“ 按端口過濾”部分中進一步描述):

C#

復制
app.UseHealthChecks("/health", port: 8000);
健康檢查選項
HealthCheckOptions提供了自定義健康檢查行為的機會:

篩選健康檢查
自定義HTTP狀態代碼
禁止緩存頭
自定義輸出
篩選健康檢查
默認情況下,運行狀況檢查中間件運行所有已注冊的運行狀況檢查。要運行運行狀況檢查的子集,請提供一個將布爾值返回到謂詞選項的函數。在以下示例中,Bar運行狀況檢查將通過其bar_tag在函數的條件語句中的標記()過濾掉,true僅在運行狀況檢查的Tags屬性與foo_tag或匹配時才返回baz_tag:

C#

復制
using System.Threading.Tasks;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.Diagnostics.HealthChecks;

public void ConfigureServices(IServiceCollection services)
{
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" });
}

public void Configure(IApplicationBuilder app)
{
app.UseHealthChecks("/health", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("foo_tag") ||
check.Tags.Contains("baz_tag")
});
}
自定義HTTP狀態代碼
使用ResultStatusCodes可以自定義健康狀態到HTTP狀態代碼的映射。以下StatusCodes分配是中間件使用的默認值。更改狀態代碼值以滿足您的要求。

在Startup.Configure:

C#

復制
//using Microsoft.AspNetCore.Diagnostics.HealthChecks;
//using Microsoft.Extensions.Diagnostics.HealthChecks;

app.UseHealthChecks("/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:

C#

復制
//using Microsoft.AspNetCore.Diagnostics.HealthChecks;
//using Microsoft.Extensions.Diagnostics.HealthChecks;

app.UseHealthChecks("/health", new HealthCheckOptions()
{
AllowCachingResponses = false
});
自定義輸出
該ResponseWriter選項獲取或設置用來寫響應的委托。默認委托使用HealthReport.Status字符串值編寫一個最小的純文本響應。

在Startup.Configure:

C#

復制
// using Microsoft.AspNetCore.Diagnostics.HealthChecks;
// using Microsoft.Extensions.Diagnostics.HealthChecks;

app.UseHealthChecks("/health", new HealthCheckOptions()
{
ResponseWriter = WriteResponse
});
默認委托使用HealthReport.Status字符串值編寫一個最小的純文本響應。以下定制委托,WriteResponse輸出定制JSON響應:

C#

復制
private static Task WriteResponse(HttpContext httpContext, HealthReport result)
{
httpContext.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 httpContext.Response.WriteAsync(
json.ToString(Formatting.Indented));
}
健康狀況檢查系統不為復雜的JSON返回格式提供內置支持,因為該格式特定於您選擇的監視系統。可以根據JObject需要隨意自定義前面的示例中的。

數據庫探針
運行狀況檢查可以指定要作為布爾測試運行的數據庫查詢,以指示數據庫是否正常響應。

該示例應用程序使用AspNetCore.Diagnostics.HealthChecks(用於ASP.NET Core應用程序的運行狀況檢查庫)對SQL Server數據庫執行運行狀況檢查。對數據庫AspNetCore.Diagnostics.HealthChecks執行SELECT 1查詢,以確認到數據庫的連接正常。

警告

使用查詢檢查數據庫連接時,請選擇一個快速返回的查詢。查詢方法冒着數據庫過載和性能下降的風險。在大多數情況下,不需要運行測試查詢。僅成功建立與數據庫的連接就足夠了。如果發現有必要運行查詢,請選擇一個簡單的SELECT查詢,例如SELECT 1。

包括對AspNetCore.HealthChecks.SqlServer的程序包引用。

在示例應用程序的appsettings.json文件中提供有效的數據庫連接字符串。該應用程序使用一個名為的SQL Server數據庫HealthCheckSample:

JSON格式

復制
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=HealthCheckSample;Trusted_Connection=True;MultipleActiveResultSets=true;ConnectRetryCount=0"
},
"Logging": {
"LogLevel": {
"Default": "Debug"
},
"Console": {
"IncludeScopes": "true"
}
}
}
在中使用AddHealthChecks注冊運行狀況檢查服務Startup.ConfigureServices。該示例應用程序AddSqlServer使用數據庫的連接字符串(DbHealthStartup.cs)調用該方法:

C#

復制
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddSqlServer(Configuration["ConnectionStrings:DefaultConnection"]);
}
在以下應用程序處理管道中調用Health Checks Middleware Startup.Configure:

C#

復制
app.UseHealthChecks("/health");
要使用示例應用程序運行數據庫探測方案,請在命令外殼程序的項目文件夾中執行以下命令:

.NET Core CLI

復制
dotnet run --scenario db
注意

Microsoft不維護或不支持AspNetCore.Diagnostics.HealthChecks。

實體框架核心DbContext探針
該DbContext檢查確認該應用程序可以與為EF Core配置的數據庫進行通信DbContext。該DbContext檢查支持的應用程序是:

使用實體框架(EF)核心。
包括對Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore的包引用。
AddDbContextCheck<TContext>為進行健康檢查DbContext。將DbContext作為TContext方法提供。重載可用於配置故障狀態,標簽和自定義測試查詢。

默認:

該DbContextHealthCheck調用EF核心的CanConnectAsync方法。您可以自定義使用AddDbContextCheck方法重載檢查運行狀況時運行的操作。
健康檢查的名稱就是TContext類型的名稱。
在示例應用程序中,AppDbContext將其提供給(DbContextHealthStartup.cs)AddDbContextCheck並注冊為服務:Startup.ConfigureServices

C#

復制
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddDbContextCheck<AppDbContext>();

services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer(
Configuration["ConnectionStrings:DefaultConnection"]);
});
}
在示例應用程序中,在中UseHealthChecks添加“運行狀況檢查中間件” Startup.Configure。

C#

復制
app.UseHealthChecks("/health");
要DbContext使用示例應用程序運行探測方案,請確認SQL Server實例中不存在由連接字符串指定的數據庫。如果數據庫存在,請將其刪除。

在命令外殼程序的項目文件夾中執行以下命令:

.NET Core CLI

復制
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):

C#

復制
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:

C#

復制
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()
{
}
}
運行狀況檢查與托管服務一起在AddCheck中注冊Startup.ConfigureServices。因為托管服務必須在運行狀況檢查中設置屬性,所以運行狀況檢查也已在服務容器(LivenessProbeStartup.cs)中注冊:

C#

復制
public void ConfigureServices(IServiceCollection services)
{
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");
});

// The following workaround permits adding an IHealthCheckPublisher
// instance to the service container when one or more other hosted
// services have already been added to the app. This workaround
// won't be required with the release of ASP.NET Core 3.0. For more
// information, see: https://github.com/aspnet/Extensions/issues/639.
services.TryAddEnumerable(
ServiceDescriptor.Singleton(typeof(IHostedService),
typeof(HealthCheckPublisherOptions).Assembly
.GetType(HealthCheckServiceAssembly)));

services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();
}
在中的應用程序處理管道中調用Health Checks Middleware Startup.Configure。在示例應用程序中,將在處創建運行狀況檢查端點,以/health/ready進行准備情況檢查和/health/live活動檢查。就緒檢查將健康檢查過濾為帶有ready標簽的健康檢查。該真人判斷濾掉StartupHostedServiceHealthCheck通過返回false的HealthCheckOptions.Predicate(有關詳細信息,請參閱篩選健康檢查):

C#

復制
app.UseHealthChecks("/health/ready", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("ready"),
});

app.UseHealthChecks("/health/live", new HealthCheckOptions()
{
Predicate = (_) => false
});
要使用示例應用程序運行就緒/活躍性配置方案,請在命令外殼中的項目文件夾中執行以下命令:

.NET Core CLI

復制
dotnet run --scenario liveness
在瀏覽器中,訪問/health/ready幾次直到15秒過去。運行狀況檢查在前15秒鍾報告不健康。15秒后,端點報告“ 健康”,這反映了托管服務已完成長時間運行的任務。

此示例還創建了運行狀況檢查發布者(IHealthCheckPublisher實現),該運行情況以兩秒的延遲運行了第一次就緒檢查。有關更多信息,請參見運行狀況檢查發布者部分。

Kubernetes示例
在諸如Kubernetes之類的環境中,使用單獨的准備情況和活動檢查很有用。在Kubernetes中,可能需要一個應用程序在接受請求之前執行耗時的啟動工作,例如測試基礎數據庫可用性。使用單獨的檢查,協調器可以區分應用程序是否正在運行但尚未准備就緒,或者應用程序無法啟動。有關Kubernetes中的就緒和活躍性探針的更多信息,請參閱Kubernetes文檔中的配置活躍性和就緒性探針。

以下示例演示了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
具有自定義響應編寫器的基於度量的探針
該示例應用程序使用自定義響應編寫器演示了內存運行狀況檢查。

MemoryHealthCheck如果應用程序使用了超過給定的內存閾值(示例應用程序中為1 GB),則會報告不健康狀態。該HealthCheckResult包括用於該應用(垃圾收集器(GC)信息MemoryHealthCheck.cs):

C#

復制
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 : HealthStatus.Unhealthy;

return Task.FromResult(new HealthCheckResult(
status,
description: "Reports degraded status if allocated bytes " +
$">= {options.Threshold} bytes.",
exception: null,
data: data));
}
}
在中使用AddHealthChecks注冊運行狀況檢查服務Startup.ConfigureServices。相反,通過它傳遞給啟用健康檢查的AddCheck中,MemoryHealthCheck被注冊為服務。所有IHealthCheck注冊的服務都可用於健康檢查服務和中間件。我們建議將運行狀況檢查服務注冊為Singleton服務。

在示例應用程序(CustomWriterStartup.cs)中:

C#

復制
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddMemoryHealthCheck("memory");
}
在中的應用程序處理管道中調用Health Checks Middleware Startup.Configure。在運行狀況檢查執行時,將為屬性WriteResponse提供一個委托ResponseWriter以輸出自定義JSON響應:

C#

復制
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHealthChecks("/health", new HealthCheckOptions()
{
// This custom writer formats the detailed status as JSON.
ResponseWriter = WriteResponse
});
}
該WriteResponse方法將格式化CompositeHealthCheckResult為JSON對象,並為運行狀況檢查響應生成JSON輸出:

C#

復制
private static Task WriteResponse(HttpContext httpContext,
HealthReport result)
{
httpContext.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 httpContext.Response.WriteAsync(
json.ToString(Formatting.Indented));
}
要使用示例應用程序運行帶有自定義響應編寫器輸出的基於度量的探針,請在命令外殼程序的項目文件夾中執行以下命令:

.NET Core CLI

復制
dotnet run --scenario writer
注意

AspNetCore.Diagnostics.HealthChecks包括基於指標的運行狀況檢查方案,包括磁盤存儲和最大值活動檢查。

Microsoft不維護或不支持AspNetCore.Diagnostics.HealthChecks。

按端口過濾
通過端口調用UseHealthChecks會將運行狀況檢查請求限制為指定的端口。通常在容器環境中使用它來公開用於監視服務的端口。

該示例應用程序使用環境變量配置提供程序配置端口。該端口在launchSettings.json文件中設置,並通過環境變量傳遞給配置提供程序。您還必須配置服務器以偵聽管理端口上的請求。

要使用示例應用程序演示管理端口配置,請在Properties文件夾中創建launchSettings.json文件。

示例應用程序中的以下Properties / launchSettings.json文件未包含在示例應用程序的項目文件中,必須手動創建:

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/"
}
}
}
在中使用AddHealthChecks注冊運行狀況檢查服務Startup.ConfigureServices。對UseHealthChecks的調用指定了管理端口(ManagementPortStartup.cs):

C#

復制
public class ManagementPortStartup
{
public ManagementPortStartup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseHealthChecks("/health", port: Configuration["ManagementPort"]);

app.Run(async (context) =>
{
await context.Response.WriteAsync(
"Navigate to " +
$"http://localhost:{Configuration["ManagementPort"]}/health " +
"to see the health status.");
});
}
}
注意

您可以通過在代碼中顯式設置URL和管理端口來避免在示例應用程序中創建launchSettings.json文件。在創建WebHostBuilder的Program.cs中,添加對UseUrls的調用,並提供應用程序的常規響應終結點和管理端口終結點。在其中調用UseHealthChecks的ManagementPortStartup.cs中,顯式指定管理端口。

Program.cs:

C#

復制
return new WebHostBuilder()
.UseConfiguration(config)
.UseUrls("http://localhost:5000/;http://localhost:5001/")
.ConfigureLogging(builder =>
{
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddConfiguration(config);
builder.AddConsole();
})
.UseKestrel()
.UseStartup(startupType)
.Build();
ManagementPortStartup.cs:

C#

復制
app.UseHealthChecks("/health", port: 5001);
要使用示例應用程序運行管理端口配置方案,請在命令外殼程序的項目文件夾中執行以下命令:

.NET Core CLI

復制
dotnet run --scenario port
分發健康檢查庫
要將健康檢查作為庫分發:

編寫將IHealthCheck接口實現為獨立類的運行狀況檢查。該類可以依賴於依賴項注入(DI),類型激活和命名選項來訪問配置數據。

在運行狀況檢查邏輯中CheckHealthAsync:

data1並且data2在運行探頭的健康檢查邏輯的方法被使用。
AccessViolationException 被處理。
當AccessViolationException發生時,FailureStatus與返回HealthCheckResult允許用戶配置健康檢查故障狀態。

C#

復制
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;

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方法中調用的參數。在以下示例中,假定以下運行狀況檢查方法簽名:

C#

復制
ExampleHealthCheck(string, string, int )
前面的簽名表示ExampleHealthCheck需要額外的數據來處理運行狀況檢查探針邏輯。使用擴展方法注冊運行狀況檢查時,會將數據提供給用於創建運行狀況檢查實例的委托。在以下示例中,調用方指定了可選的:

健康檢查名稱(name)。如果null,example_health_check被使用。
健康檢查(data1)的字符串數據點。
健康檢查(data2)的整數數據點。如果null,1被使用。
故障狀態(HealthStatus)。默認值為null。如果為null,則報告失敗狀態為HealthStatus.Unhealthy。
標簽(IEnumerable<string>)。
C#

復制
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接口有一個方法:

C#

復制
Task PublishAsync(HealthReport report, CancellationToken cancellationToken);
HealthCheckPublisherOptions允許您設置:

延遲 –應用程序啟動后在執行IHealthCheckPublisher實例之前應用的初始延遲。延遲在啟動時應用一次,不適用於后續迭代。默認值為五秒鍾。
時間段– IHealthCheckPublisher執行的時間段。默認值為30秒。
斷言 -如果斷言是null(默認),健康檢查服務出版商運行所有登記的醫療檢查。要運行運行狀況檢查的子集,請提供一個過濾檢查集的功能。該謂詞在每個期間都會進行評估。
超時 –對所有IHealthCheckPublisher實例執行運行狀況檢查的超時。使用InfiniteTimeSpan可以執行而不會超時。默認值為30秒。
警告

在ASP.NET Core 2.2發行版中,IHealthCheckPublisher實現不支持設置Period。它設置Delay的值。此問題已在ASP.NET Core 3.0中解決。

在示例應用程序中,ReadinessPublisher是IHealthCheckPublisher實現。將為每個檢查記錄運行狀況檢查狀態,如下所示:

健康檢查狀態為“ 健康”的信息(LogInformation)。
如果狀態為“ 已降級”或“ 不正常”,則顯示錯誤(LogError)。
C#

復制
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就緒檢查具有兩秒鍾的啟動延遲,並且每30秒運行一次檢查。為了激活IHealthCheckPublisher實現,該示例ReadinessPublisher在依賴項注入(DI)容器中注冊為單例服務:

C#

復制
public void ConfigureServices(IServiceCollection services)
{
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");
});

// The following workaround permits adding an IHealthCheckPublisher
// instance to the service container when one or more other hosted
// services have already been added to the app. This workaround
// won't be required with the release of ASP.NET Core 3.0. For more
// information, see: https://github.com/aspnet/Extensions/issues/639.
services.TryAddEnumerable(
ServiceDescriptor.Singleton(typeof(IHostedService),
typeof(HealthCheckPublisherOptions).Assembly
.GetType(HealthCheckServiceAssembly)));

services.AddSingleton<IHealthCheckPublisher, ReadinessPublisher>();
}
注意

以下解決方法允許在將一個或多個其他托管服務添加到應用程序后,將IHealthCheckPublisher實例添加到服務容器。ASP.NET Core 3.0不需要此解決方法。

C#

復制
private const string HealthCheckServiceAssembly =
"Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckPublisherHostedService";

services.TryAddEnumerable(
ServiceDescriptor.Singleton(typeof(IHostedService),
typeof(HealthCheckPublisherOptions).Assembly
.GetType(HealthCheckServiceAssembly)));
注意

AspNetCore.Diagnostics.HealthChecks包括多個系統的發布者,包括Application Insights。

Microsoft不維護或不支持AspNetCore.Diagnostics.HealthChecks。

使用MapWhen限制運行狀況檢查
使用MapWhen可以有條件地為健康檢查端點分支請求管道。

在以下示例中,MapWhen如果收到針對api/HealthCheck端點的GET請求,則分支請求管道以激活“運行狀況檢查中間件” :

C#

復制
app.MapWhen(
context => context.Request.Method == HttpMethod.Get.Method &&
context.Request.Path.StartsWith("/api/HealthCheck"),
builder => builder.UseHealthChecks());

app.UseMvc();
有關更多信息,請參見ASP.NET Core中間件。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM