다음을 통해 공유


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.Diagnostics.ResourceMonitoring;
using Microsoft.Extensions.Hosting;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddResourceMonitoring();

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();

앞의 코드가 하는 역할은 다음과 같습니다.

참고 항목

Microsoft.Extensions.Diagnostics.HealthChecks.ResourceUtilization 라이브러리는 소비자가 AddResourceMonitoring에 대한 종속 호출을 등록한다고 가정합니다. 등록하지 않으면 HealthCheckService를 확인할 때 예외가 throw됩니다.

애플리케이션 수명 상태 검사

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 메서드를 정의합니다.
  • 호출자 이름 및 취소 토큰을 캡처한 다음 HealthCheckService 인스턴스에서 상태 검사를 요청하는 사용자 지정 CheckHealthAsync 메서드를 정의합니다. 그러면 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();
    }
}

앞의 코드가 하는 역할은 다음과 같습니다.

  • builder 변수로 할당되는 새 HostApplicationBuilder 인스턴스를 만듭니다.
  • ExampleService를 앱의 유일한 IHostedService로 등록합니다.
  • AddHealthChecks 호출에서 반환된 IHealthChecksBuilder 인스턴스의 호출을 AddApplicationLifecycleHealthCheck 확장 메서드에 연결하여 IHostApplicationLifetime의 애플리케이션 수명 이벤트에 대한 상태 검사를 추가합니다.
    • healthChecksBuilder 인스턴스를 사용하여 상태 검사를 더 추가할 수 있습니다.
  • IHost 인스턴스를 app 변수로 빌드합니다.
  • 서비스 공급자로부터 IHostedService를 가져옵니다. 이것이 ExampleService 인스턴스입니다.
  • 다음 두 개의 작업 참조를 고려해 Task.WhenAll을 호출합니다.
    • 500밀리초 동안 지연된 다음 ExampleService 인스턴스에서 ReadyAsync 메서드를 호출하는 DelayAndReportAsync 메서드가 상태 검사를 평가합니다.
    • RunAsync(IHost, CancellationToken) 메서드가 app을 시작합니다.

앱은 다음 순서로 로그를 출력하여 수명 주기 이벤트와 관련된 상태 검사의 상태를 보고합니다.

  1. StartingAsync: 비정상
  2. StartAsync: 비정상
  3. StartedAsync: 비정상
  4. ReadyAsync: 정상
  5. StoppingAsync: 비정상
  6. StopAsync: 비정상
  7. StoppedAsync: 비정상

즉, 이 공급자는 애플리케이션 인스턴스가 준비된 경우에만 트래픽을 수신하도록 합니다. ASP.NET Core를 사용하여 웹앱을 개발하는 경우 상태 검사 미들웨어를 사용할 수 있습니다. 자세한 내용은 ASP.NET Core의 상태 검사를 참조하세요.

참고 항목