健康检查
HealthCheckMiddleware类
需要引用Microsoft.Extensions.Diagnostics.HealthChecks Nuget包,使用IHealthCheck接口来操作健康监测的方法。
注册健康检查所依赖的核心服务
在Program类
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks();
var app = builder.Build();
app.UseHealthChecks("/health");
app.Run();
- 通过IServiceCollection 接口的AddHealthChecks扩展方法去注册。
- 通过WebApplication 对象调用UseHealthChecks扩展方法来注入中间件,并将 /health 作为健康检查终节点指定的路径。
通过AddCheck()来自定义逻辑处理
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks().AddCheck("default",Check);
var app = builder.Build();
app.UseHealthChecks("/health");
app.Run();
HealthCheckResult Check()
{
var aaa = new Random().Next(1,4);
return aaa switch
{
1 => HealthCheckResult.Healthy(),
2 => HealthCheckResult.Unhealthy(),
3 => HealthCheckResult.Degraded(),
};
}
通过多次刷新网址,可以看到返回不同的健康状态。
改变响应状态码
var healthCheckOpt = new HealthCheckOptions()
{
ResultStatusCodes =
{
[HealthStatus.Healthy] = 298,
[HealthStatus.Unhealthy] = 420,
[HealthStatus.Degraded] = 299
}
};
app.UseHealthChecks("/health",healthCheckOpt);
自定义响应内容
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks()
.AddCheck("Foo", Check)
.AddCheck("Bar",Check)
.AddCheck("Baz",Check);
var app = builder.Build();
var healthCheckOpt = new HealthCheckOptions()
{
ResponseWriter = ReportAsync
};
app.UseHealthChecks("/health",healthCheckOpt);
app.Run();
HealthCheckResult Check()
{
var aaa = new Random().Next(1, 4);
return aaa switch
{
1 => HealthCheckResult.Healthy(),
2 => HealthCheckResult.Unhealthy(),
3 => HealthCheckResult.Degraded(),
};
}
static Task ReportAsync(HttpContext context,HealthReport report)
{
var result = JsonConvert.SerializeObject(
new
{
status = report.Status.ToString(),
responseTimeStamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds(),
errors = report.Entries.Select(x=>new { key = x.Key,value = Enum.GetName(typeof(HealthStatus),x.Value.Status) })
});
context.Response.ContentType = MediaTypeNames.Application.Json;
return context.Response.WriteAsync(result);
}
发布健康报告
通过IHealthCheckPublisher 接口实现自定义发送逻辑
public class SimplePublisher : IHealthCheckPublisher
{
public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
{
if(report.Status == HealthStatus.Healthy) Console.ForegroundColor = ConsoleColor.Green;
else Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{DateTime.UtcNow} Prob Status: {report.Status}");
var sb = new StringBuilder();
foreach (var name in report.Entries.Keys)
{
sb.AppendLine($"{name} : {report.Entries[name].Status}");
}
cancellationToken.ThrowIfCancellationRequested();
Console.WriteLine(sb);
Console.ResetColor();
return Task.CompletedTask;
}
}
在Program中注册
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHealthChecks()
.AddCheck("Foo", Check)
.AddCheck("Bar",Check)
.AddCheck("Baz",Check);
builder.Services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Period = TimeSpan.FromSeconds(5);
});
builder.Services.AddSingleton<IHealthCheckPublisher, SimplePublisher>();
var app = builder.Build();
var healthCheckOpt = new HealthCheckOptions()
{
ResponseWriter = ReportAsync
};
app.UseHealthChecks("/health",healthCheckOpt);
app.Run();
HealthCheckResult Check()
{
var aaa = new Random().Next(1, 4);
return aaa switch
{
1 => HealthCheckResult.Healthy(),
2 => HealthCheckResult.Unhealthy(),
3 => HealthCheckResult.Degraded(),
};
}
HealthCheckPublisherOptions对象
- Delay : 服务启动后收集工作的延后时间
- Period : 健康报告发布时间间隔
- Predicate : 对IHealthCheck对象进行过滤
- Timeout :对象超时时间