简介
健康检查,其实这个名称已经很明确了,它是检查你的应用程序是否健康运行的一种方式。随着当前各类项目越来越多的应用程序正在转向微服务式架构,健康检查就变得尤为关键。虽然微服务体系结构具有许多好处,但其中一个缺点就是为了确保所有这些服务都正常运行的操作开销更高。你不在是监视一个庞大的整体项目的健康状况,而是需要监控许多不同服务的状态,甚至这些服务通常只负责一件事情。健康检查(Heatlh Checks)通常与一些服务发现工具结合使用,如Consul ,来监控您的微服务器,来观测您的服务是否健康运行。
健康检查有很多种不同的方法,但最常见的方法是将HTTP端点暴露给专门用于健康检查的应用程序。一般来说,如果一切情况都很好,你的服务将返回200的状态码,然而任何非200的代码则意味着出现问题。例如,如果发生错误,你可能会返回500以及一些出错的JSON信息。
举例一些常见的健康检查内容:
- 检查我的服务可以连接到数据库吗?
- 检查我的服务可以查询第三方API吗?
- 可能做一些只读操作
- 我的服务可以访问文件系统吗(IO是否正常)?
- 检查我的服务占用的内存或CPU是否高于某个阈值?
健康检查有三个登记
- Healthy 健康
- Unhealthy 不良
- Degraded 降级
ASP.NET Core实现
Neget安装以下包
AspNetCore.HealthChecks.UI
AspNetCore.HealthChecks.UI.Client
AspNetCore.HealthChecks.UI.InMemory.Storage
Microsoft.Extensions.Diagnostics.HealthChecks
添加检查测试案例
services.AddHealthChecks()
.AddCheck("Foo", () =>
HealthCheckResult.Healthy("健康"), tags: new[] { "foo_tag" })
.AddCheck("Bar", () =>
HealthCheckResult.Unhealthy("不良"), tags: new[] { "bar_tag" })
.AddCheck("Baz", () =>
HealthCheckResult.Degraded("降级"), tags: new[] { "baz_tag" });
添加检查
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace WebApplication6.HealthChecks
{
public class DatabaseHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken =
default)
{
try
{
return Task.FromResult(HealthCheckResult.Healthy($"API is running."));
}
catch (Exception ex)
{
return Task.FromResult(HealthCheckResult.Unhealthy("DB is not Healthy", ex));
}
}
}
}
appsettings.json
添加HealthChecksUI
配置
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"HealthChecks-UI": {
"HealthChecks": [
{
"Name": "Local",
"Uri": "http://localhost:5000/health"
}
//{
// "Name": "",
// "Uri": ""
//}
],
"Webhooks": [
{
"Name": "",
"Uri": "",
"Payload": "",
"RestoredPayload": ""
}
],
"EvaluationTimeOnSeconds": 10,
"MinimumSecondsBetweenFailureNotifications": 60
}
}
Startup
添加HealthCheck
服务和HealthCheckUI
界面
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using WebApplication6.HealthChecks;
namespace WebApplication6
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHealthChecks()
.AddCheck("Foo", () =>
HealthCheckResult.Healthy("健康"), tags: new[] { "foo_tag" })
.AddCheck("Bar", () =>
HealthCheckResult.Unhealthy("不良"), tags: new[] { "bar_tag" })
.AddCheck("Baz", () =>
HealthCheckResult.Degraded("降级"), tags: new[] { "baz_tag" });
//添加DatabaseHealthCheck
services.AddHealthChecks().AddCheck<DatabaseHealthCheck>(nameof(DatabaseHealthCheck));
//添加UI 内存存储
services.AddHealthChecksUI().AddInMemoryStorage();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseHealthChecksUI();
HealthCheckOptions healthCheckOptions = new HealthCheckOptions
{
AllowCachingResponses = false,
Predicate = _ => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse,
ResultStatusCodes =
{
[HealthStatus.Healthy] = StatusCodes.Status200OK,
[HealthStatus.Unhealthy] = StatusCodes.Status503ServiceUnavailable,
[HealthStatus.Degraded] = StatusCodes.Status500InternalServerError,
[HealthStatus.Degraded] = StatusCodes.Status419AuthenticationTimeout
}
};
app.UseHealthChecks("/health", healthCheckOptions);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
访问http://localhost:5000/health
查看健康检查
访问http://localhost:5000/healthchecks-ui
查看健康检查UI界面