系列导航及源代码

需求

应用健康检查在容器部署的微服务场景下非常常见,相比而言单体非容器部署的应用就不太关心这个特性,为了后续的内容我们在本文中简单介绍一下如何实现应用程序的健康检查功能。

目标

实现TodoList的健康检查功能。

原理与思路

.NET框架从.NET Core 2.2版本开始引入了相关的功能,同时AspNetCore.Diagnostics.HealthChecks包提供了更为丰富的健康检查功能,包括数据库,消息总线,Redis和ElasticSearch的健康检查。

健康检查探针(probe)分为三种:

  • readiness probes:应用程序就绪探针,判断当前应用程序是否已经启动。
  • liveness probes: 应用程序存活探针,判断当前应用程序是否出于活动状态。
  • startup probes:应用程序功能探针,一般我们用hc来表示其端口,可以用来判断应用程序内部功能是否正常(比如判断数据库连接是否正常,判断Redis连接是否正常之类)。

在本文中我们不过多地发散,通过创建一个自定义的健康检查对象来实现。

实现

自定义健康检查,实现IHealthCheck接口

Microsoft.Extensions.Diagnostics.HealthChecks

using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace TodoList.Application.Common;

public class ApplicationHealthCheck : IHealthCheck
{
private static readonly Random _rnd = new (); public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
var result = _rnd.Next(5) == 0
? HealthCheckResult.Healthy()
: HealthCheckResult.Unhealthy("Failed random"); return Task.FromResult(result);
}
}

添加服务和中间件

首先在Application/DependencyInjection中添加健康检查服务:

  • DependencyInjection.cs
services.AddHealthChecks().AddCheck<ApplicationHealthCheck>("Random Health Check");

然后修改Program中间件配置如下:

  • Program.cs
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseHttpLogging(); app.MapDefaultControllerRoute();
app.MapHealthChecks("/liveness");
app.MapHealthChecks("/ready");
app.MapHealthChecks("/hc");

验证

启动Api项目,执行健康检查的三个GET接口,截图我只贴其中一个,因为我们在实现健康检查的时候,采用了随机数返回Healthy或者Unhealthy的方式,所以多请求几次,应该能看到下面的响应:

一点扩展

关于Smart probes和Dumb probes

  • 所谓Smart probes最典型的目的就是为了验证应用程序是否能正确工作,像一开始所说的,它可以用来探测外部依赖如数据库、消息队列、甚至是其他API的连接是否正常,程序在这些地方是否可以按预期工作。
  • 相对而言,Dumb probes典型的应用目的是用来判断应用程序没有崩溃,它并不检查功能及依赖上的正确性,通常表现为HTTP的直接响应。

推荐的使用方式是:

  • 对于liveness检查,使用dumb probes就可以了,因为只要能够响应HTTP请求,就可以证明应用程序没有崩溃。
  • 对于startup或者称作真正的“健康”检查hc,使用smart probes,因为这时候不仅要保证程序没有崩溃,我们还需要某种程度的功能及依赖的健康检查,以证明程序能够按预期工作。
  • 对于readiness检查,需要根据实际的需求来看,如果我们没有定义特殊的应用程序“就绪”标准,使用dumb probes就可以;反之如果我们需要进行某种程度的逻辑检查来定义“就绪”,那么就需要使用smart probes

设置Dumb健康检查接口

修改中间件配置:

  • Program.cs
app.MapHealthChecks("/liveness", new HealthCheckOptions { Predicate = r => r.Name.Contains("self") });
app.MapHealthChecks("/ready", new HealthCheckOptions { Predicate = _ => false });

这时候我们再去请求健康检查,这两个接口已经固定返回Healthy结果了,hc接口依然按照我们之前设置的进行随机返回。

总结

本文我们简单地实现了健康检查接口,目前还不太能看得出来作用,但是当我们进行容器化部署,或是进行k8s部署时,健康检查探针的作用就比较明显了。关于健康检查,更多用法请参考官方文档:Health checks in ASP.NET Core

参考资料

  1. AspNetCore.Diagnostics.HealthChecks
  2. Adding health checks with Liveness, Readiness, and Startup probes
  3. Health checks in ASP.NET Core

使用.NET 6开发TodoList应用(28)——实现应用程序健康检查的更多相关文章

  1. 使用.NET 6开发TodoList应用(3)——引入第三方日志库

    需求 在我们项目开发的过程中,使用.NET 6自带的日志系统有时是不能满足实际需求的,比如有的时候我们需要将日志输出到第三方平台上,最典型的应用就是在各种云平台上,为了集中管理日志和查询日志,通常会选 ...

  2. 使用.NET 6开发TodoList应用(1)——系列背景

    前言 想到要写这样一个系列博客,初衷有两个:一是希望通过一个实践项目,将.NET 6 WebAPI开发的基础知识串联起来,帮助那些想要入门.NET 6服务端开发的朋友们快速上手,对使用.NET 6开发 ...

  3. 使用.NET 6开发TodoList应用(2)——项目结构搭建

    为了不影响阅读的体验,我把系列导航放到文章最后了,有需要的小伙伴可以直接通过导航跳转到对应的文章 : P TodoList需求简介 首先明确一下我们即将开发的这个TodoList应用都需要完成什么功能 ...

  4. 使用.NET 6开发TodoList应用(4)——引入数据存储

    需求 作为后端CRUD程序员(bushi,数据存储是开发后端服务一个非常重要的组件.对我们的TodoList项目来说,自然也需要配置数据存储.目前的需求很简单: 需要能持久化TodoList对象并对其 ...

  5. 使用.NET 6开发TodoList应用(5)——领域实体创建

    需求 上一篇文章中我们完成了数据存储服务的接入,从这一篇开始将正式进入业务逻辑部分的开发. 首先要定义和解决的问题是,根据TodoList项目的需求,我们应该设计怎样的数据实体,如何去进行操作? 长文 ...

  6. 使用.NET 6开发TodoList应用(5.1)——实现Repository模式

    需求 经常写CRUD程序的小伙伴们可能都经历过定义很多Repository接口,分别做对应的实现,依赖注入并使用的场景.有的时候会发现,很多分散的XXXXRepository的逻辑都是基本一致的,于是 ...

  7. 使用.NET 6开发TodoList应用(6)——使用MediatR实现POST请求

    需求 需求很简单:如何创建新的TodoList和TodoItem并持久化. 初学者按照教程去实现的话,应该分成以下几步:创建Controller并实现POST方法:实用传入的请求参数new一个数据库实 ...

  8. 使用.NET 6开发TodoList应用文章索引

    系列导航 使用.NET 6开发TodoList应用(1)--系列背景 使用.NET 6开发TodoList应用(2)--项目结构搭建 使用.NET 6开发TodoList应用(3)--引入第三方日志 ...

  9. 使用.NET 6开发TodoList应用(7)——使用AutoMapper实现GET请求

    系列导航 使用.NET 6开发TodoList应用文章索引 需求 需求很简单:实现GET请求获取业务数据.在这个阶段我们经常使用的类库是AutoMapper. 目标 合理组织并使用AutoMapper ...

随机推荐

  1. MH/T4029.3 IFPL报文解析

    MH/T4029.3是民航业用来规定飞行计划相关数据交互的规范,今天我们先来解析下其中I类的IFPL报文. 我们先来看看IFPL报文长啥样. ZCZC -TITLE IFPL -FILTIM 0109 ...

  2. mvn 把本地jar包打包到本地仓库中

    命令如下: mvn install:install-file -Dfile=apache-ant-zip-2.3.jar -DgroupId=com.ckfinder -DartifactId=apa ...

  3. 使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可

    使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可

  4. 使用.NET 6开发TodoList应用(5.1)——实现Repository模式

    需求 经常写CRUD程序的小伙伴们可能都经历过定义很多Repository接口,分别做对应的实现,依赖注入并使用的场景.有的时候会发现,很多分散的XXXXRepository的逻辑都是基本一致的,于是 ...

  5. JAVA中Map集合遍历

    for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println("key= " ...

  6. c++设计模式概述之外观

    类写的不够规范,目的是缩短篇幅,请实际中不要这样做. 1.概述 了解外观模式相关概念后,一下子想到的是主板, 主板上有各种元器件,各种指示灯,各种电容,各种电路.然而,主板供电的接口就一个,其他元器件 ...

  7. 【LeetCode】1154. Day of the Year 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 计算1月1号之间天数 日期 题目地址:https:// ...

  8. 【LeetCode】946. Validate Stack Sequences 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 模拟过程 日期 题目地址:https://leetc ...

  9. Pydantic使用

    Pydantic可以在代码运行时提供类型提示, 数据校验失败时提供友好的错误提示, 使用Python的类型注解来进行数据校验和settings管理 一般使用 from datetime import ...

  10. SuperPixel

    目录 SLIC Superpixel algorithm 距离函数的选择 代码 Gonzalez R. C. and Woods R. E. Digital Image Processing (For ...