• ASP.NET Core-使用HealthCheck对程序健康检查


    正文

    在开发AspNet Core应用的时候,我们经常会为该应用公布一个特殊的检测接口出来。该接口的目的很简单,告诉外界程序当前程序现在是可以访问或者不能访问的,便于外界做出相应的操作,比如监控报警,页面通知用户稍作等待等。

    在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” 路径。

    运行状况检查

    但是在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
    }
    

    或许还有许许多多的检查项:FileSizeHealthCheckRedisHealthCheck等等。当我们将它们都添加上之后,则只有当所有的检查器都返回为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)。

    自定义返回内容对咱们定位错误和记录日志十分有用。

    第三方支持

    虽然官方为我们提供的运行检查库已经足够轻量和简单。但是为了避免重复造轮子,我们可以使用AspNetCore.Diagnostics.HealthChecks包,该项目包含了许多情况的检查,比如 Sql ServerMySqlElasticsearchRedisKafka等等。

    并且还为我们提供一个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:

    默认是没有任何的检测配置项的,如果咱们需要可视化运行状态,需要添加配置:

    "HealthChecksUI": {
    "HealthChecks": [
    {
    "Name": "db_check",
    "Uri": "http://localhost:5000/db_health"
    }
    ],
    "EvaluationTimeinSeconds": 10,
    "MinimumSecondsBetweenFailureNotifications": 60
    }

    再次查看UI界面

    转:https://www.cnblogs.com/uoyo/p/12396644.html

  • 相关阅读:
    ES6基础知识
    浏览器相关的前端知识
    JavaScript基础知识汇总
    HTML(超文本标记语言)基础知识汇总
    CSS相关基础知识汇总
    NYOJ 737 石子合并(一)
    HDU 1051 Wooden Sticks
    NY 325 zb的生日
    HDU 2068 RPG的错排
    HDU 1284 钱币兑换问题
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/12773543.html
Copyright © 2020-2023  润新知