ASP.NET Core 中的健康监控
每个软件工程师的梦想都是以这样一种方式编写代码,使他们不会有任何缺陷,并且他们的任何基础设施都不会出现故障。但是,在现实世界中并非如此,并且使用微服务架构,识别容器的状态变得更加困难。
事实上,我们需要一个适当的机制来快速识别并尽早解决问题。这就是健康监测的用武之地。
ASP.NET Core 中的健康监控允许您获得容器的近实时状态。当您的应用程序处理数据库、缓存、url、消息代理等组件时,这些监控机制非常方便。
实施基本健康监测
在开发 ASP.NET Core 微服务时,您可以通过使用 nuget 包Microsoft.Extension.Diagnostic.HealthCheck来使用内置的健康监控功能。这些健康监控功能可以通过使用一组服务和中间件来启用。
public void ConfigureServices
(IServiceCollection services)
{
services.AddControllers();
services.AddHealthChecks();
}
public void Configure(IApplicationBuilder app,
IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHealthChecks("/api/health");
}
}
运行应用程序时,您将看到输出为 Healthy
对于两行代码,还不错。但是,我们可以做得更好。
以 JSON 格式返回状态
默认情况下,健康监控的输出是“纯文本”。因此,我们可以将健康状态视为“健康”或“不健康”。为了查看所有依赖项的详细输出,必须使用AspNetCore.HealthChecks.UI.Client中可用的“ResponseWriter”属性自定义应用程序
首先,添加nuget包
dotnet add package AspNetCore.HealthChecks.UI
dotnet add package AspNetCore.HealthChecks.UI.Client
现在,让我们配置应用程序
endpoints.MapHealthChecks("/api/health",
new HealthCheckOptions()
{
Predicate = _ => true,
ResponseWriter = UIResponseWriter.
WriteHealthCheckUIResponse
});
现在,运行应用程序,您将看到 json 格式的输出
{
"status": "Healthy",
"totalDuration": "00:00:00.0038176"
}
URI 的健康状况
您可以使用 nuget 包轻松验证端点/uri 的状态
dotnet add package AspNetCore.HealthChecks.uris
现在,让我们修改我们的代码以适应 uri
public void ConfigureServices
(IServiceCollection services)
{
services.AddControllers();
services.AddHealthChecks()
.AddUrlGroup(new Uri
("https://localhost:5001/weatherforecast"),
name: "base URL", failureStatus:
HealthStatus.Degraded)
}
您需要使用 AddUrlGroup 方法来验证 uri,如果失败,则 url 的状态将显示为 Degraded。
现在,运行应用程序和输出将看起来相似
{
"status": "Healthy",
"totalDuration": "00:00:00.1039166",
"entries": {
"base URL": {
"data": {},
"duration": "00:00:00.0904980",
"status": "Healthy",
"tags": []
}
}
SQL Server 的运行状况
为了验证 SQL Server 数据库的状态,我在 docker 中进行了数据库安装;但是,您可以使用数据库服务器的本地实例。
您可以使用以下命令在 docker 中安装 SQL Server
//Docker pull command to install
docker pull mcr.microsoft.com/mssql/server
//Docker Run command
docker run --privileged -e 'ACCEPT_EULA=Y'
-e 'SA_PASSWORD=Winter2019' -p 1433:1433
--name=MSSQL -d
mcr.microsoft.com/mssql/server:latest
数据库启动并运行后,添加以下 nuget 包
dotnet add package AspNetCore.HealthChecks.SqlServer
public void ConfigureServices
(IServiceCollection services)
{
services.AddControllers();
services.AddHealthChecks()
.AddUrlGroup(new Uri("https://localhost:5001/weatherforecast"), name: "base URL", failureStatus: HealthStatus.Degraded) .AddSqlServer(Configuration.GetConnectionString("DefaultConnection"),
healthQuery: "select 1",
failureStatus: HealthStatus.Degraded,
name: "SQL Server");
}
注意:在 HealthQuery 中,不要使用任何花哨的查询来验证数据库连接。使用“Select 1”的主要目的是减少执行时间。
现在运行应用程序,您的输出将看起来相似
{
"status": "Healthy",
"totalDuration": "00:00:00.1039166",
"entries": {
"base URL": {
"data": {},
"duration": "00:00:00.0904980",
"status": "Healthy",
"tags": []
},
"SQL Server": {
"data": {},
"duration": "00:00:00.0517363",
"status": "Healthy",
"tags": []
}
}
}
自定义健康检查
使用 IHealthCheck 接口可以轻松实现自定义健康检查。
public class TodoHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
//Implement you logic here
var healthy = true;
if (healthy)
return Task.FromResult(HealthCheckResult.Healthy());
return Task.FromResult(HealthCheckResult.Unhealthy());
}
}
配置服务中的 AddCheck 方法用于添加指定名称的健康检查。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHealthChecks()
.AddUrlGroup(new Uri("https://localhost:5001/weatherforecast"), name: "base URL", failureStatus: HealthStatus.Degraded)
.AddSqlServer(Configuration.GetConnectionString("DefaultConnection"),
healthQuery: "select 1",
failureStatus: HealthStatus.Degraded,
name: "SQL Server")
.AddCheck<TodoHealthCheck>("Todo Health Check",failureStatus:HealthStatus.Unhealthy);
}
现在,运行应用程序
{
"status": "Healthy",
"totalDuration": "00:00:00.0544065",
"entries": {
"base URL": {
"data": {},
"duration": "00:00:00.0527285",
"status": "Healthy",
"tags": []
},
"SQL Server": {
"data": {},
"duration": "00:00:00.0386450",
"status": "Healthy",
"tags": []
},
"Todo Health Check": {
"data": {},
"duration": "00:00:00.0001681",
"status": "Healthy",
"tags": []
}
}
}
让我们形象化
以 JSON 格式显示输出看起来合理;然而,可视化 UI 更有意义,并且对于非技术背景的人来说也很容易理解。
添加nuget包
dotnet add package AspNetCore.HealthChecks.UI.InMemory.Storage
要可视化 UI 健康检查,您需要修改服务和中间件的更改。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHealthChecks()
.AddUrlGroup(new Uri("https://localhost:5001/weatherforecast"), name: "base URL", failureStatus: HealthStatus.Degraded)
.AddSqlServer(Configuration.GetConnectionString("DefaultConnection"),
healthQuery: "select 1",
failureStatus: HealthStatus.Degraded,
name: "SQL Server")
.AddCheck<TodoHealthCheck>("Todo Health Check",failureStatus:HealthStatus.Unhealthy);
services.AddHealthChecksUI(opt =>
{
opt.SetEvaluationTimeInSeconds(10); //time in seconds between check
opt.MaximumHistoryEntriesPerEndpoint(60); //maximum history of checks
opt.SetApiMaxActiveRequests(1); //api requests concurrency
opt.AddHealthCheckEndpoint("default api", "/api/health"); //map health check api
})
.AddInMemoryStorage();
}
健康检查 UI 端点默认为“ /healthchecks-ui ”。您可以通过 MapHealthCheckUI 方法自定义此值来更改它。
在代码中,我将轮询间隔设置为 10 秒。它检查应用程序中的所有端点/数据库等是否按预期工作。
现在运行应用程序
现在,让我们从 Docker 容器中停止 SQL Server 并验证输出
//Get Container ID
docker ps
//Stop Docker container for SQL Server
docker stop <Container Id here>
其他健康检查功能
运行状况监控不仅限于 SQL Server 和 URI。但是,它支持大量的功能和细节可以在这里找到
结论
在微服务或基于容器的架构中,必须包含健康监控,如果没有这个功能,生命将是可衡量的。借助此运行状况监控功能,您和您的团队可以以稳健和标准化的方式对服务的运行状况采取行动。
Asp.Net Core 团队为健康检查添加了一流的支持,使开发人员可以轻松构建和自定义。
我希望你喜欢这篇文章。如果您觉得这篇文章很有趣,请点赞并分享。
常见问题FAQ
- 程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
- 请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!