【五分钟的dotnet】是一个利用您的碎片化时间来学习和丰富.net知识的博文系列。它所包含了.net体系中可能会涉及到的方方面面,好比C#的小细节,AspnetCore,微服务中的.net知识等等。 5min+不是超过5分钟的意思,"+"是知识的增长。so,它是让您花费5分钟如下的时间来提高您的知识储备量。html
在开发AspNet Core应用的时候,咱们常常会为该应用公布一个特殊的检测接口出来。该接口的目的很简单,告诉某一些外界程序(好比docker,客户端等)这个程序如今是能够访问或者不能访问的,便于外界作出相应的操做,好比监控报警,页面通知用户稍做等待等。git
在AspNet Core 2.2 以前,若是咱们要实现一个这样的检测接口,须要创建一个单独的controller,好比HealthController
。而后为其实现一个简单的检测方法:github
[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来作出相应的反应。sql
可是在Aspnet Core 2.2 以后,咱们有了新的解决方式。只须要简单的操做就能够进行程序运行情况的检查。docker
咱们只须要在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自带了这些功能。json
此时咱们能够访问 "/health"
路径,将会看到对应结果:app
若是程序正常,则返回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扩展。
最后,偷偷说一句:创做不易,点个推荐吧.....
原文出处:https://www.cnblogs.com/uoyo/p/12396644.html