【5min+】保持程序健康的秘诀!AspNetCore的HealthCheck
系列介绍
【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net知识等等。
5min+不是超过5分钟的意思,"+"是知识的增加。so,它是让您花费5分钟以下的时间来提升您的知识储备量。
正文
在开发AspNet Core应用的时候,我们经常会为该应用公布一个特殊的检测接口出来。该接口的目的很简单,告诉某一些外界程序(比如docker,客户端等)这个程序现在是可以访问或者不能访问的,便于外界做出相应的操作,比如监控报警,页面通知用户稍作等待等。
在AspNet Core 2.2 之前,如果我们要实现一个这样的检测接口,需要建立一个单独的controller,比如HealthController
。然后为其实现一个简单的检测方法:
[Route("working")]
public ActionResult Working()
{
using (var connection = new SqlConnection(_connectionString))
{
try
{
connection.Open();
}
catch (SqlException)
{
return new HttpStatusCodeResult(503, "Generic error");
}
}
return new EmptyResult();
}
该接口目的是检测应用与数据库的连接能否成功。如果成功连接,则返回状态码为200
的空内容,如果失败则返回503
。 外界程序可以通过定时访问 “\working”
路径,根据返回的对应Code来做出相应的反应。
运行状况检查
但是在Aspnet Core 2.2 之后,我们有了新的解决方式。只需要简单的操作就可以进行程序运行状况的检查。
我们只需要在Startup.cs
中添加两句话就OK了:
public void ConfigureServices(IServiceCollection services)
{
//使用该扩展方法
services.AddHealthChecks();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
//使用该扩展方法
endpoints.MapHealthChecks("/health");
});
}
默认情况是不需要在额外的引入其它nuget包的,因为AspNet Core自带了这些功能。
此时我们可以访问 "/health"
路径,将会看到对应结果:
如果程序正常,则返回Http状态码为200
,显示内容为"Healthy"的结果。如果程序不正常,则返回Http状态码为503
,显示内容为"UnHealthy"的结果。
这就是运行状况检查的初步使用。
为什么要自检?
看到这里,可能有些同学要问:“我引入一个检测到底有什么用?什么情况下我需要这么做呢?”
其实,对咱们的应用程序来说,做运行情况检查是非常有必要的。
就好比去医院看病的时候,医生往往会问病人:“你现在是感觉哪儿不舒服,对哪些药物过敏”等等问题。然后才能对症下药。
更形象的一个例子是做体检:人们一般会自费花钱定期去医院做体检,如果发现哪一检查项有异常的时候,就会报告给医院并且去寻找对应的医生,向医生说明情况之后得到对应的治疗方案。
所以咱们的应用程序也是一样的,“定期体检”有必要吗? 肯定是有必要的。如果不定期体检,我们很难知道现在程序运行状态到底是什么样子,或许它已经“濒临崩溃”了,需要立即释放内存。
还有一点就是:需要如实的报告检查情况。就如同医生问病人:“您哪不舒服?”,病人说:“我没病。我哪儿都没问题” 。 那医生只会认为病人是来搞笑的,所以放弃对他的治疗。
始终要相信一点,没有人比你自己更懂你自己。虽然外界的程序也会有各种其它方式来判断应用程序是否正常,但是它只能知道大概,只有程序体本身才能更清楚的知道现在运行的情况。
目的性的检查
最初我们只是简单的引入了 AddHealthChecks
。 但是它并没有任何特定的逻辑在里面。而现实场景我们是需要对各种指标进行检查的,就好比体检单上有多个体检项一样。所以我们需要实现自定义的检查功能。
比如咱们现在要实现一个对Sql Server 连接情况的检查。我们只需要实现 IHealthCheck
接口,实现CheckHealthAsync
方法就可以了:
public class SqlServerHealthCheck : IHealthCheck
{
SqlConnection _connection;
public string Name => "sql";
public SqlServerHealthCheck(SqlConnection connection)
{
_connection = connection;
}
public Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
try
{
_connection.Open();
}
catch (SqlException)
{
return Task.FromResult(HealthCheckResult.Unhealthy("From Sql Serve"));
}
return Task.FromResult(HealthCheckResult.Healthy());
}
}
然后在Startup.cs
的AddHealthChecks
进行扩展:
services.AddHealthChecks()
.AddCheck<SqlServerHealthCheck>("sql_check");
此时如果咱们再次访问"/health"
路径,就会发现应用会执行SqlServerHealthCheck
里面的检查逻辑。
但是实际情况,咱们往往都会有许许多多的检查项,比如增加一个叫做MemoryHealthCheck
的检查项:
public class MemoryHealthCheck : IHealthCheck
{
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
//doing some memory check things.
return Task.FromResult(HealthCheckResult.Healthy());
}
}
// startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddCheck<SqlServerHealthCheck>("sql_check")
.AddCheck<MemoryHealthCheck>("memory_check"); // add this line
}
或许还有许许多多的检查项:FileSizeHealthCheck
,RedisHealthCheck
等等。当我们将它们都添加上之后,则只有当所有的检查器都返回为Healthy
的时候,才会认为是健康。
但是某些情况我们又只想进行单项检查怎么办呢? 我们可以在 endpoints 的配置中新增另外的路由映射规则:
// startup.cs
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
Predicate = s => s.Name.Equals("sql_check"),
ResponseWriter = WriteResponse
});
endpoints.MapHealthChecks("/healthy", new HealthCheckOptions()
{
Predicate = s => s.Name.Equals("memory_check"),
ResponseWriter = WriteResponse
});
});
//指定返回格式
private static Task WriteResponse(HttpContext context, HealthReport result)
{
context.Response.ContentType = "application/json";
var json = new JObject(
new JProperty("status", result.Status.ToString()),
new JProperty("results", new JObject(result.Entries.Select(pair =>
new JProperty(pair.Key, new JObject(
new JProperty("status", pair.Value.Status.ToString()),
new JProperty("description", pair.Value.Description),
new JProperty("data", new JObject(pair.Value.Data.Select(
p => new JProperty(p.Key, p.Value))))))))));
return context.Response.WriteAsync(
json.ToString());
}
我们在原有的基础上增加了HealthCheckOptions
的参数,该参数指定了关于状态检测的匹配规则,返回状态码,返回格式等信息。
上面的代码我们指定了两个路由。当访问"health"
路径的时候,则是对sql连接的检查(根据检查器名来匹配:Name.Equals("sql_check")),而访问"healthy"
路径的时候,是对内存的检查。 最后还为他们指定了需要返回的内容(WriteResponse)。
接下来我们再次进行请求"health"
路径,就会得到下面的结果:
自定义返回内容对咱们定位错误和记录日志十分有用。(就像看病的例子,病人更清晰的描述病情,医生就能够更容易定位病因。)。
第三方支持
虽然官方为我们提供的运行检查库已经足够轻量和简单。但是为了避免重复造轮子,我们可以使用AspNetCore.Diagnostics.HealthChecks包,该项目包含了许多情况的检查,比如 Sql Server
、MySql
、Elasticsearch
、Redis
、Kafka
等等。
并且还为我们提供一个UI界面,可供查看。只需要在原有的基础上引入对应的代码就行了:
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddCheck<SqlServerHealthCheck>("sql_check")
.AddCheck<MemoryHealthCheck>("memory_check");
// add this line
services.AddHealthChecksUI();
}
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions()
{
Predicate = s => s.Name.Equals("sql_check"),
ResponseWriter = WriteResponse
});
//add this line
endpoints.MapHealthChecksUI();
});
当我们访问"/healthchecks-ui"
路径时,就可以看到这样的UI:
默认是没有任何的检测配置项的,如果咱们需要可视化运行状态,需要在AddHealthChecksUI
中进行配置:
services.AddHealthChecksUI(setupSettings: setup =>
{
setup.AddHealthCheckEndpoint("endpoint1", "http://localhost:5001/health");
});
再次查看UI界面,就能看到对应的检查项:
总结
本篇文章主要为大家介绍了 aspnet core 2.2之后所推出的“HealthCheck”,与使用传统的Controller 公开API进行检查不同,使用“IHealthCheck”能够更快速的进行访问(毕竟不需要进行模型绑定等操作),而且IHealthCheck
接口能够更好的进行检查项扩展。让我们能够更快更清楚的了解到应用程序运行的情况。
当然,由于篇幅有限,本来还想继续拓展IHealthCheckPublisher
接口和健康检查的实现原理等内容,就放在以后再说吧。如果您对该功能感兴趣可以查看 《ASP.NET Core 中的运行状况检查》和第三方HealthChecks扩展。
最后,偷偷说一句:创作不易,点个推荐吧.....
【5min+】保持程序健康的秘诀!AspNetCore的HealthCheck的更多相关文章
- kubernetes--应用程序健康检查
版权声明:本文属于原创,欢迎转载,转载请保留出处:http://blog.csdn.net/liyingke112 http://blog.csdn.net/liyingke112/article/d ...
- [置顶]
kubernetes--应用程序健康检查
K8S的应用程序健康检查分为livenessProbe和readinessProbe,两者相似,但两者存在着一些区别. livenessProbe在服务运行过程中检查应用程序是否运行正常,不正常将杀掉 ...
- 使用.NET 6开发TodoList应用(28)——实现应用程序健康检查
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 应用健康检查在容器部署的微服务场景下非常常见,相比而言单体非容器部署的应用就不太关心这个特性,为了后续的内容我们在本文中简单介 ...
- 【5min+】美化API,包装AspNetCore的返回结果
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...
- windows环境下如何搭建Consul+Ocelot
下面的是markdown格式的文档,懒得排版了,有兴趣的话可以去github上看,有源码 Github:https://github.com/yuchengao0721/Consul-Ocelot.g ...
- 【Web探索之旅】第四部分:Web程序员
内容简介 1.第四部分第一课:什么是Web程序员? 2.第四部分第二课:如何成为Web程序员? 3.第四部分第三课:成为优秀Web程序员的秘诀 第四部分:Web程序员(完结篇) 大家好.终于来到了[W ...
- 10分钟实现dotnet程序在linux下的自动部署
背景 一直以来,程序署都是非常麻烦且无聊的事情,在公司一般都会有 devops 方案,整个 cicd 过程涉及的工具还是挺多的,搭建起来比较麻烦.那么对于一些自己的小型项目,又不想搭建一套这样的环境, ...
- 微信小程序开源项目库汇总
最近做了一个微信小程序开源项目库汇总,里面集合了OpenDigg 上的优质的微信小程序开源项目库,方便移动开发人员便捷的找到自己需要的项目工具等,感兴趣的可以到GitHub上给个star. UI组件 ...
- 微信小程序开源项目库集合
UI组件 weui-wxss ★852 - 同微信原生视觉体验一致的基础样式库 Wa-UI ★122 - 针对微信小程序整合的一套UI库 wx-charts ★105 - 微信小程序图表工具 wema ...
随机推荐
- ubuntu19.10——snap错误has install-snap change in progress
使用软件商店安装时遇到问题 snap has install-snap change in progress 原因是之前的安装错误终止,使得现在的安装无法进行,解决方案: 终端输入: snap cha ...
- windowsserver的应用升级部署坑
jar文件的后缀名要打开显示,否者备份的‘.bak20190820’可能后面还是jar可执行文件,以至于mybatis这类xml映射器的namespace方法重复扫上去导致注册tomcat conte ...
- 十、linux-mysql下的mysql数据库增量恢复
1.全量备份 全量数据就是数据库中所有的数据,全量备份就是把数据库中所有的数据进行备份. 备份所有库: mysqldump -uroot -ppoldboy -S /data/3306/mysql.s ...
- 76)PHP,session数据区的使用
(1)session数据区: 在我们的session会话结束之前,会有一个seeeion的文件,存储着session序列化的数据,在会话没有结束之前,我们都是操作$_SESSION的,但是在会话结束后 ...
- python-django框架-电商项目-首页开发_20191122
python-django框架-电商项目-首页开发 业务背景: 用户浏览网站一定是先到首页, 没有登陆的话首页内容完全一样,而且是不经常变化的, 一段时间内,有100用户访问,就要有几个用户就要查询多 ...
- HihoCode-1323-回文字符串
参考博客: https://blog.csdn.net/mitsuha_/article/details/76690634 https://blog.csdn.net/u014142379/artic ...
- [LC] 80. Remove Duplicates from Sorted Array II
Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...
- nodejs 模块变量 应用
exports.allcodeandname=(function(){ var fs = require('fs'); var data = fs.readFileSync(__dirname+'/a ...
- 吴裕雄--天生自然HTML学习笔记:HTML 表格
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Dubbo的集群容错与负载均衡策略
Dubbo的集群容错策略 正常情况下,当我们进行系统设计时候,不仅要考虑正常逻辑下代码该如何走,还要考虑异常情况下代码逻辑应该怎么走.当服务消费方调用服务提供方的服务出现错误时候,Dubbo提供了多种 ...