C# 中的 .NET 应用运行状况检查

在分布式系统中,运行状况检查定期评估各个节点或服务的状态、可用性和性能。 这些检查可确保系统正常运行且高效。 运行状况检查对于系统可靠性至关重要,并且通常定期执行运行状况检查,并针对决策和纠正措施分析的结果。

以下运行状况检查状态结果是可能的:

此外,运行状况检查通常报告各种诊断指标。 有关详细信息,请参阅诊断指标:Microsoft.Extensions.Diagnostics.HealthChecks

资源利用率运行状况检查

若要对 .NET 应用的资源利用率执行运行状况检查,请添加对 Microsoft.Extensions.Diagnostics.HealthChecks.ResourceUtilization 的包引用。 在 IServiceCollection 实例上,将 AddHealthChecks 的调用链接到 AddResourceUtilizationHealthCheck。 以下示例演示如何使用AddResourceUtilizationHealthCheck扩展方法将资源利用率运行状况检查添加到 IServiceCollection 实例:

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddHealthChecks()
    .AddResourceUtilizationHealthCheck();

var app = builder.Build();

var healthCheckService = app.Services.GetRequiredService<HealthCheckService>();

var result = await healthCheckService.CheckHealthAsync();

Console.WriteLine($"{result.Status} {result.TotalDuration}");

app.Run();

前面的代码:

应用程序生存期运行状况检查

若要对 IHostApplicationLifetime 的应用程序生存期事件执行运行状况检查,请使用 Microsoft.Extensions.Diagnostics.HealthChecks.Common NuGet 包中提供的 AddApplicationLifecycleHealthCheck 扩展方法。

此提供程序将指示仅当应用程序完全处于活动状态时,应用程序才正常。 在生存期对象指示应用程序已启动之前,提供程序将报告应用程序不正常。 当应用程序开始关闭时,提供程序会将应用程序报告为不正常。

该库会公开一个 HealthCheckService,使使用者可以随时请求运行状况检查。 请考虑以下 ExampleService 实现:

using System.Runtime.CompilerServices;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

internal class ExampleLifecycle(
    HealthCheckService healthCheckService,
    ILogger<ExampleLifecycle> logger) : IHostedLifecycleService
{
    Task IHostedService.StartAsync(
        CancellationToken cancellationToken) =>
        CheckHealthAsync(cancellationToken: cancellationToken);

    Task IHostedLifecycleService.StartedAsync(
        CancellationToken cancellationToken) =>
        CheckHealthAsync(cancellationToken: cancellationToken);

    Task IHostedLifecycleService.StartingAsync(
        CancellationToken cancellationToken) =>
        CheckHealthAsync(cancellationToken: cancellationToken);

    Task IHostedService.StopAsync(
        CancellationToken cancellationToken) =>
        CheckHealthAsync(cancellationToken: cancellationToken);

    Task IHostedLifecycleService.StoppedAsync(
        CancellationToken cancellationToken) =>
        CheckHealthAsync(cancellationToken: cancellationToken);

    Task IHostedLifecycleService.StoppingAsync(
        CancellationToken cancellationToken) =>
        CheckHealthAsync(cancellationToken: cancellationToken);

    public Task ReadyAsync() => CheckHealthAsync();

    private async Task CheckHealthAsync(
         [CallerMemberName] string eventName = "",
         CancellationToken cancellationToken = default)
    {
        HealthReport result =
            await healthCheckService.CheckHealthAsync(cancellationToken);

        logger.LogInformation(
            "{EventName}: {Status}", eventName, result.Status);
    }
}

前面的代码:

  • 定义实现 IHostedService 接口的新 ExampleLifecycle 类。
  • 定义接受以下参数的主要构造函数:
  • 实现 IHostedLifecycleService 接口,每个方法调用 CheckHealthAsync 方法。
  • 定义调用 CheckHealthAsync 方法的 ReadyAsync 方法。
  • 定义一个自定义 CheckHealthAsync 方法,该方法捕获调用方名称和取消令牌,然后从 HealthCheckService 实例请求运行状况检查。 然后记录 result

运行状况检查服务报告 HealthStatus.Healthy 状态的唯一时间是在应用启动之后和调用停止之前。 请考虑以下 Program.cs

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

var healthChecksBuilder = builder.Services
    .AddHostedService<ExampleLifecycle>()
    .AddHealthChecks()
    .AddApplicationLifecycleHealthCheck();

// You could use the healthChecksBuilder instance to add more checks...

var app = builder.Build();

var services = app.Services.GetRequiredService<IEnumerable<IHostedService>>();

await Task.WhenAll(DelayAndReportAsync(services), app.RunAsync());

static async Task DelayAndReportAsync(IEnumerable<IHostedService> services)
{
    // Ensure app started...
    await Task.Delay(500);

    var service = services.FirstOrDefault(static s => s is ExampleLifecycle);
    if (service is ExampleLifecycle example)
    {
        await example.ReadyAsync();
    }
}

前面的代码:

应用按以下顺序输出日志,报告运行状况检查状态,因为它与生命周期事件相关:

  1. StartingAsync:运行不正常
  2. StartAsync:运行不正常
  3. StartedAsync:运行不正常
  4. ReadyAsync:运行正常
  5. StoppingAsync:运行不正常
  6. StopAsync:运行不正常
  7. StoppedAsync:运行不正常

换句话说,此提供程序可确保应用程序实例在准备就绪时仅接收流量。 如果要使用 ASP.NET Core 开发 Web 应用,可以使用运行状况检查中间件。 有关详细信息,请参阅 ASP.NET Core 中的运行状况检查

另请参阅