ASP.NET Core之跨平台的实时性能监控(2.健康检查)

前言

上篇我们讲了如何使用App Metrics 做一个简单的APM监控,最后提到过健康检查这个东西.

这篇主要就是讲解健康检查的内容.

没看过上篇的,请移步:ASP.NET Core之跨平台的实时性能监控

首先我们来了解一下什么是健康检查(health checks)?

1.什么是健康检查?

       健康检查,其实这个名称已经很明确了,它是检查你的应用程序是否健康运行的一种方式。随着当前各类项目越来越多的应用程序正在转向微服务式架构,健康检查就变得尤为关键。虽然微服务体系结构具有许多好处,但其中一个缺点就是为了确保所有这些服务都正常运行的操作开销更高。你不在是监视一个庞大的整体项目的健康状况,而是需要监控许多不同服务的状态,甚至这些服务通常只负责一件事情。健康检查(Heatlh Checks)通常与一些服务发现工具结合使用,如Consul  ,来监控您的微服务器,来观测您的服务是否健康运行。

2.如何实施健康检查?

       健康检查有很多种不同的方法,但最常见的方法是将HTTP端点暴露给专门用于健康检查的应用程序。一般来说,如果一切情况都很好,你的服务将返回200的状态码,然而任何非200的代码则意味着出现问题。例如,如果发生错误,你可能会返回500以及一些出错的JSON信息。

3.健康检查的常见情况

你的健康检查将基于你的应用程序或者你的微服务主要在做写什么事情,就检查什么.

不过我们也可以举例一些常见的健康检查内容:

  • 检查我的服务可以连接到数据库吗?
  • 检查我的服务可以查询第三方API吗?
    • 可能做一些只读操作
  • 我的服务可以访问文件系统吗(IO是否正常)?
  • 检查我的服务占用的内存或CPU是否高于某个阈值?

下面我们就来讲解一下,如何使用App Metrics来实现我们的健康检查.

效果如图:

正文

这里就不创建新的项目了,直接拿上个项目的例子来写.

App Metrics中的健康检查分为3种状态:

1.健康(绿),2.亚健康(黄),3.不健康(红).  颜色如上图所示

也含有一些内置的健康检查(后面讲解),我们先来讲一下如何自行创建健康检查

1.创建自己的健康检查

首先我们在Demo中创建一个健康检查的文件夹(当然,也可以是类库)

创建类,取名为 OKHealthCheck,继承HealthCheck(引用:using App.Metrics.Health),代码如下:

 public class OKHealthCheck: HealthCheck
    {
        public OKHealthCheck() : base("正常的检查(OKHealthCheck)") { }

        protected override Task<HealthCheckResult> CheckAsync(CancellationToken token = default(CancellationToken))
        {
            //返回正常的信息
            return Task.FromResult(HealthCheckResult.Healthy("OK"));
        }
    }

然后在Startup注入中,加入健康检查的注入

            services.AddMetrics(options =>
            {
                options.GlobalTags.Add("app", "sample app");
                options.GlobalTags.Add("env", "stage");
            })
               .AddHealthChecks()//这里是健康检查的注入
               .AddJsonSerialization()
               .AddReporting(
                  factory =>
                  {
                      factory.AddInfluxDb(
                new InfluxDBReporterSettings
                {
                    InfluxDbSettings = new InfluxDBSettings(database, uri),
                    ReportInterval = TimeSpan.FromSeconds(5)
                });
                  })
               .AddMetricsMiddleware(options => options.IgnoredHttpStatusCodes = new[] { 404 });

值得注意的是,这里的健康检查注入,是通过反射实现的,他会自动检测你项目引用的dll,找到继承过HealthCheck的类,自动全部注入.

然后我们运行,会发现我们的Grafana的健康检查仪表盘,多了条数据,如图:

(注:这里说明一下这个Apdex Score(用户满意度得分),是默认自动开启的.可以通过配置关闭)

上面我们演示了如何创建一个自己的健康检查,但是只返回了健康的信息,我们还有亚健康,不健康,这些当然也是会出现的.所以,代码如下:

返回不健康的信息:

protected override Task<HealthCheckResult> CheckAsync(CancellationToken token = default(CancellationToken))
        {
            return Task.FromResult(HealthCheckResult.Unhealthy("不健康")); //重点是这里
        }

返回亚健康

 protected override Task<HealthCheckResult> CheckAsync(CancellationToken token = default(CancellationToken))
        {
            return Task.FromResult(HealthCheckResult.Degraded("Degraded"));
        }

在这个方法中,加上你们自己的检查业务逻辑,返回相应的HealthCheckResult即可.

2.使用内置的健康检查

   前面我们说过,App Metrics给我们提供了一些内置的健康检查,我们下面就来一一讲解

   2.1内置的HTTP检测

    我们直接在AddHealthChecks中注入,使用方法如下,:

.AddHealthChecks(factory=> {
//通过HTTP访问GitHub,看是否正常,间隔10秒
 factory.RegisterHttpGetHealthCheck("github是否访问正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10));
 })//这里是健康检查的注入

   2.2内置的Ping检测

   代码如下:

               .AddHealthChecks(factory=> {

                   //通过HTTP访问GitHub,看是否正常,间隔10秒
                   factory.RegisterHttpGetHealthCheck("github是否访问正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10));
                   //检测是否能Ping通百度
                   factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10));

               })//这里是健康检查的注入

2.3内置物理内存占用检测

说明一下,这个是检测当前程序占用的物理内存是否超过你设置阀值(字节为单位),并不是检测你还剩下多少物理内存

               .AddHealthChecks(factory=> {

                   //通过HTTP访问GitHub,看是否正常,间隔10秒
                   factory.RegisterHttpGetHealthCheck("github是否访问正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10));
                   //检测是否能Ping通百度
                   factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10));
                   //检测占用内存是否超过2G
                   factory.RegisterProcessPhysicalMemoryHealthCheck("占用内存是否超过阀值(2G)", (2048L * 1024L) * 1024L);

               })//这里是健康检查的注入

2.4内置专用内存占用检测

说明一下,这个方法,通过源码可以看到,获取的是PrivateMemorySize64,也是就是获取为关联的进程分配的专用内存量。

               .AddHealthChecks(factory=> {

                   //通过HTTP访问GitHub,看是否正常,间隔10秒
                   factory.RegisterHttpGetHealthCheck("github是否访问正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10));
                   //检测是否能Ping通百度
                   factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10));
                   //检测占用内存是否超过2G
                   factory.RegisterProcessPhysicalMemoryHealthCheck("占用内存是否超过阀值(2G)", (2048L * 1024L) * 1024L);
                   //检测专用内存占用量是否超过阀值(2G)
                   factory.RegisterProcessPrivateMemorySizeHealthCheck("专用内存占用量是否超过阀值(2G)", (2048L * 1024L) * 1024L);

               })//这里是健康检查的注入

2.5内置虚拟内存占用检测

没啥好说的,直接上代码:

               .AddHealthChecks(factory=> {

                   //通过HTTP访问GitHub,看是否正常,间隔10秒
                   factory.RegisterHttpGetHealthCheck("github是否访问正常", new Uri("https://github.com/"), TimeSpan.FromSeconds(10));
                   //检测是否能Ping通百度
                   factory.RegisterPingHealthCheck("百度 ping", "baidu.com", TimeSpan.FromSeconds(10));
                   //检测占用内存是否超过2G
                   factory.RegisterProcessPhysicalMemoryHealthCheck("占用内存是否超过阀值(2G)", (2048L * 1024L) * 1024L);
                   //检测专用内存占用量是否超过阀值(2G)
                   factory.RegisterProcessPrivateMemorySizeHealthCheck("专用内存占用量是否超过阀值(2G)", (2048L * 1024L) * 1024L);
                   //检测虚拟内存占用是否超过阀值(2G)
                   factory.RegisterProcessVirtualMemorySizeHealthCheck("虚拟内存占用量是否超过阀值(2G)", (2048L * 1024L) * 1024L);

               })//这里是健康检查的注入

最后,我们把代码跑起来.~,效果如图

写在最后

至此,今天的内容就结束了.

有趣的是,其实微软在ASP.NET Core 2.0中其实也给我们内置了相关的健康检测插件.(说明健康检测真的很重要)

https://github.com/dotnet-architecture/HealthChecks

有兴趣的朋友可以去看看.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

开源的作业调度框架 - Quartz.NET

Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.n...

2356
来自专栏DOTNET

Entity Framework——建模建库

1数据库初始化策略选择 三种初始化策略: 1)CreateDatabaseIfNotExists:默认的策略。如果数据库不存在,那么就创建数据库。但是如果数据库...

2867
来自专栏纯洁的微笑

springcloud(十):服务网关zuul初级篇

前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud...

2788
来自专栏MYSQL轻松学

防止连接Mysql超时,JDBC探活配置

我们知道Mysql有两个关于连接超时的参数,默认为8小时: MySQL > show global variables like '%timeout%'; wa...

3659
来自专栏程序你好

REST API和SOAP API之间的区别

The Representational State Transfer (REST)架构风格不是可以购买的技术,也不是可以添加到软件开发项目中的库。REST是一...

601
来自专栏解Bug之路

MySql协议讲解-事务协议篇

MySql事务协议主要是通过set autocommit、commit以及rollback这三个报文(命令)来实现的。

492
来自专栏玩转前端

flutter全局数据共享通知方案

让我们先抛开Flutter这个平台说话,如果让你实现数据共享,你能想到的基础方案有哪些。

33718
来自专栏北京马哥教育

如何快速截取某段时间内的日志

在排除故障时,需要分析发生故障的原因,避免再次出现同样的问题,需要对日志进行分析,截取故障前后时间段的日志。通常用正则表达式来获取某段时间的内的日志,比较繁琐。...

2556
来自专栏程序员的SOD蜜

“设计应对变化”--实例讲解一个数据同步系统

 系列文章索引: [WCF邮件通信系统应用 之 数据同步程序 之 设计内幕 之 一] 同步一个数据库要发多少个数据包? [WCF邮件通信系统应用 之 数据同步...

2067
来自专栏恰同学骚年

NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例

  “消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。消息被发送到队列中,“消息队列”是在消息的传...

742

扫码关注云+社区