在我的 ASP.NET Core 应用程序中,我实现了
IHealthCheck
以返回状态 503
,直到应用程序预热完成。但是当我从 Postman 调用此端点时,我在输出中只看到状态字符串,而不是实际的 JSON:
Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckResult
为什么我没有得到完整的 JSON 响应?我期望一个与此类似的 JSON:
{
"Status": "Healthy",
"Description": "The Initialization task has completed."
}
相反,我看到:
健康
IHealthCheck 依赖于另一个对象来获取应用程序预热的状态。根据它返回健康或不健康。
public class StartupHealthCheck : IHealthCheck
{
private volatile bool _isReady;
private readonly IGlobalState _globalState;
public StartupHealthCheck(IGlobalState globalState)
=> _globalState = globalState;
public bool StartupCompleted
{
get => _isReady;
set => _isReady = value;
}
public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
if (StartupCompleted && _globalState.PercentageInitialized == 100)
{
return HealthCheckResult.Healthy("The Initialization task has completed.");
}
return new HealthCheckResult(HealthStatus.Unhealthy, $"The Initialization task is still running at - {_globalState.PercentageInitialized}%.");
}
}
您需要在 Program.cs 中自定义输出响应,例如:
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))
{
var healthCheck = result.Entries.FirstOrDefault().Value;
writer.WriteStartObject();
writer.WriteString("Status", healthCheck.Status.ToString());
writer.WriteString("Description", healthCheck.Description);
writer.WriteEndObject();
}
var json = Encoding.UTF8.GetString(stream.ToArray());
return context.Response.WriteAsync(json);
}
}
在.NET 6或更高版本中,在Program.cs中注册服务:
builder.Services.AddSingleton<IGlobalState, GlobalState>(); // Assuming IGlobalState is registered
builder.Services.AddHealthChecks()
.AddCheck<StartupHealthCheck>("startup_health_check");
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = WriteResponse
});
});
app.UseAuthorization();
app.MapControllers();
app.Run();
参考:自定义输出