asp.net core에서 health Check는 해당 어플리케이션이 정상적으로 작동하는지 확인하는 기능입니다.
위 기능으로는 크게 아래와 같이 활용 가능합니다.
- 애플리케이션의 가용성 모니터링: Health Check는 애플리케이션이 정상적으로 작동하는지 확인하는데 사용됩니다. 이를 통해 시스템이 언제든지 사용할 수 있는지 여부를 판단할 수 있습니다.
- 종속 서비스 상태 확인: 데이터베이스, 캐시, 외부 API 등 애플리케이션이 의존하고 있는 서비스들의 상태를 확인할 수 있습니다. 만약 종속 서비스 중 하나가 비정상 상태라면, 이를 즉시 감지하고 조치를 취할 수 있습니다.
- 컨테이너 오케스트레이션 도구 통합: Kubernetes와 같은 컨테이너 오케스트레이션 도구에서는 애플리케이션의 상태를 확인하기 위해 Health Check를 사용합니다. 이러한 도구들은 Health Check의 결과를 바탕으로 컨테이너를 재시작하거나 다른 노드로 이동시킬 수 있습니다.
- 로드 밸런서와의 통합: 로드 밸런서는 Health Check를 통해 애플리케이션 인스턴스의 상태를 확인하고, 비정상 상태의 인스턴스에 트래픽을 보내지 않도록 할 수 있습니다
- 애플리케이션 성능 및 신뢰성 향상: Health Check를 통해 애플리케이션의 다양한 구성 요소들의 상태를 주기적으로 모니터링함으로써, 사전에 문제를 발견하고 대응할 수 있습니다.
우선 health check를 사용하려면 NuGet패키지를 설치해야합니다.
dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks
위 명령어로 패키지를 다운로드하고
program.cs
builder.Services.AddHealthChecks();
var app = builder.Build();
app.MapHealthChecks("/testCheck");
위와 같이 미들웨어를 구성하고
프로그램 실행후 주소창에 미들웨어에서 입력한 /testCheck를 입력하면 이상이 없을때 healty라는 화면이 보이게 됩니다.
또한 health check를 커스텀하여 사용할 수 있는데 CustomHealthCehck클래스를 생성하여 그안에 로직이나 사용자 지정문구와 같은 내용을 작성할 수 있습니다.
class CustomHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
var isHealthy = true;
if (isHealthy)
{
return Task.FromResult(HealthCheckResult.Healthy("All systems are looking good"));
}
return Task.FromResult(new HealthCheckResult(context.Registration.FailureStatus, "System Unhealty"));
}
}
builder.Services.AddHealthChecks()
.AddCheck<CustomHealthCheck>("Custom Health Check", failureStatus: HealthStatus.Degraded, tags: new[] { "custom" })
failureStatus: Health Check가 실패했을때 반환 상태를 지정하는것 입니다.
- Healthy: 시스템이 정상적으로 작동하고 있음을 나타냅니다. Health Check가 성공했을 때 반환됩니다.
- Degraded: 시스템이 작동 중이지만 일부 문제가 있음을 나타냅니다. 이는 성능 저하나 부분적인 장애를 의미할 수 있습니다. Health Check가 일부 문제를 발견했을 때 반환될 수 있습니다.
- Unhealthy: 시스템에 심각한 문제가 있음을 나타냅니다. 이는 시스템이 정상적으로 작동하지 않거나 주요 기능이 중단되었음을 의미합니다. Health Check가 실패했을 때 반환됩니다.
tags : 태그를 지정하여 그룹화나 필터링을 하여 선택적으로 모니터링이 가능하게 됩니다.
app.MapHealthChecks("/healthcheck", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
Predicate = healthcheck => healthcheck.Tags.Contains("custom"),
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
},
ResponseWriter = WriteResponse
});
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("result");
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.WriteAsJsonAsync(Encoding.UTF8.GetString(memoryStream.ToArray()));
}
- app.MapHealthChecks("매핑엔드포인트", ...): 해당 부분에 엔드포인트에 대해 헬스 체크를 매핑합니다.
- new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions: 헬스 체크 옵션을 정의합니다.
- ResultStatusCodes = { ... }: 헬스 체크 상태에 따른 HTTP 응답 상태 코드를 설정합니다.
- HealthStatus.Healthy] = StatusCodes.Status200OK: 시스템이 건강할 때 200 OK 응답을 반환합니다.
- [HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable: 시스템이 불건강할 때 503 서비스 사용 불가 응답을 반환합니다.
- [HealthStatus.Degraded] = StatusCodes.Status200OK: 시스템 상태가 저하되었을 때도 200 OK 응답을 반환합니다.
그리고 json으로 health Check의 관한 내용을 return하게 됩니다.
ef-core를 사용한다 가정하면 efcore healthcheck를 통해서 해당 db가 정상적으로 작동하는지도 확인이 가능합니다.
builder.Services.AddHealthChecks()
.AddCheck<CustomHealthCheck>("Custom Health Check", failureStatus: HealthStatus.Degraded, tags: new[] { "custom" })
.AddSqlServer(connectionString, tags: new[] { "database" })//db연결가능 체크
.AddDbContextCheck<testDbContext>(tags: new[] { "database" });
이때 알맞은 db에 맞게 메서드를 지정하고 AddDbContextCheck메서드에 체크할 dbcontext객체를 넣어 타입을 지정합니다.
그리고 tag를 database로 필터링하여 MapHealthChecks를 지정해주면 db 상태에 관한 healthcheck도 가능해집니다.
app.MapHealthChecks("/databasehealthcheck", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
{
Predicate = healthcheck => healthcheck.Tags.Contains("database"),
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
[HealthStatus.Degraded] = StatusCodes.Status200OK,
},
ResponseWriter = WriteResponse
});
그리고 실행하면 데이터베이스의 상태에 대한 결과가 아래와 같이 출력되게 됩니다.
1.databasehealthcheck
2.healthcheck
'c# > ASP.NET CORE' 카테고리의 다른 글
ASP.NET CORE 전역 에러 처리 Global Error Exception (0) | 2024.03.09 |
---|---|
ASP.NET CORE AutoMapper 사용법 (0) | 2024.03.05 |