• 给 asp.net core 写一个简单的健康检查


    给 asp.net core 写一个简单的健康检查

    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"

    healthy

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

    unhealthy

    End

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

  • 相关阅读:
    ARM-Linux S5PV210 UART驱动(1)----用户手册中的硬件知识
    可变参数列表---以dbg()为例
    《C和指针》 读书笔记 -- 第7章 函数
    《Visual C++ 程序设计》读书笔记 ----第8章 指针和引用
    支持异步通知的globalfifo平台设备驱动程序及其测试代码
    linux内核中sys_poll()的简化分析
    《C和指针》读书笔记——第五章 操作符和表达式
    测试方法-等价类划分法
    MonkyTalk学习-8-Agent
    MonkyTalk学习-7-Verify-Verify
  • 原文地址:https://www.cnblogs.com/weihanli/p/a-simple-healthcheck-for-aspnetcore.html
Copyright © 2020-2023  润新知