视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
如何给asp.net core写个简单的健康检查
2020-11-27 22:34:34 责编:小采
文档


Intro

健康检查可以帮助我们知道应用的当前状态是不是处于良好状态,现在无论是 docker 还是 k8s 还是现在大多数的服务注册发现大多都提供了健康检查机制来检测应用的健康状态,如果应用本身就提供一个健康检查的机制会更友好,更能真实的反映出应用的健康状态。

我们的开发环境虚拟机配置有点低,所以有时候虚拟机会卡死。导致接口无响应,有时可能有些服务启动有问题会挂掉,所以需要一个简单的健康检查机制去检查应用的健康状态来第一时间知道应用出现异常。

健康检查扩展实现

实现源码

 public static IApplicationBuilder UseHealthCheck(this IApplicationBuilder applicationBuilder)
 {
 return UseHealthCheck(applicationBuilder, new PathString("/api/health"));
 }

 public static IApplicationBuilder UseHealthCheck(this IApplicationBuilder applicationBuilder, string path)
 {
 return UseHealthCheck(applicationBuilder, new PathString(path));
 }

 public static IApplicationBuilder UseHealthCheck(this IApplicationBuilder applicationBuilder, PathString path)
 {
 applicationBuilder.Map(path, builder => builder.Use(
 (context, next) =>
 {
 context.Response.StatusCode = 200;
 return context.Response.WriteAsync("healthy");
 }));
 return applicationBuilder;
 }

 public static IApplicationBuilder UseHealthCheck(this IApplicationBuilder applicationBuilder, string path, Func<IServiceProvider, bool> checkFunc)
 {
 return UseHealthCheck(applicationBuilder, new PathString(path), serviceProvider => Task.FromResult(checkFunc(serviceProvider)));
 }

 public static IApplicationBuilder UseHealthCheck(this IApplicationBuilder applicationBuilder, string path,
 Func<IServiceProvider, Task<bool>> checkFunc)
 {
 return UseHealthCheck(applicationBuilder, new PathString(path), checkFunc);
 }

 public static IApplicationBuilder UseHealthCheck(this IApplicationBuilder applicationBuilder, PathString path, Func<IServiceProvider, bool> checkFunc)
 {
 if (checkFunc == null)
 {
 checkFunc = serviceProvider => true;
 }
 return UseHealthCheck(applicationBuilder, path, serviceProvider => Task.FromResult(checkFunc(serviceProvider)));
 }

 public static IApplicationBuilder UseHealthCheck(this IApplicationBuilder applicationBuilder, PathString path, Func<IServiceProvider, Task<bool>> checkFunc)
 {
 if (checkFunc == null)
 {
 checkFunc = serviceProvider => Task.FromResult(true);
 }
 applicationBuilder.Map(path, builder => builder.Use(
 async (context, next) =>
 {
 try
 {
 var healthy = await checkFunc.Invoke(context.RequestServices);
 if (healthy)
 {
 context.Response.StatusCode = StatusCodes.Status200OK;
 await context.Response.WriteAsync("healthy");
 }
 else
 {
 context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
 await context.Response.WriteAsync("unhealthy");
 }
 }
 catch (Exception ex)
 {
 context.RequestServices.GetService<ILoggerFactory>().CreateLogger("HealthCheck").Error(ex);
 context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
 await context.Response.WriteAsync("unhealthy");
 }
 }));
 return applicationBuilder;
 }

配置健康检查

在 Startup 里配置健康检查,示例代码

app.UseHealthCheck(); // 最基本的健康检查, 默认检查路径为 ""/api/health",直接返回 healthy
app.UseHealthCheck("/heath"); // 配置健康检查的路径为 "/health",直接返回 healthy

app.UseHealthCheck("/health", serviceProvider =>
 {
 // 检查数据连接是否正常,这里只是一个示例,可以根据需要自定义自己的实现
 var configuration = serviceProvider.GetService<IConfiguration>();
 var connString = configuration.GetConnectionString("DefaultConnection");
 try
 {
 using (var conn = new SqlConnection(connString))
 {
 conn.EnsureOpen();
 }
 return true;
 }
 catch (Exception)
 {
 return false;
 }
 });

实际效果

直接启动访问 "/health"

数据库连接改为一个错误的连接,修改数据库名称为一个不存在的数据库

End

这个实现比较简单,只是实现一个比较简单的检查,最初的想法比较简单只是看某个应用是否正常工作,具体的检查逻辑可以自定义。官方的 HealthChecks 的实现稍为复杂,下次单独写一篇文章介绍。

好了,

下载本文
显示全文
专题