midwayjs / midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈

Home Page:https://www.midwayjs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

健康检查生命周期

czy88840616 opened this issue · comments

Discussed in #3354

Originally posted by mariodu October 24, 2023
组件不健康的可能导致应用异常,需要用健康检查机制反馈,让应用摘除流量,防止异常情况发生。

外部 health check -> midway framework health check -> componet health check

设计目标

  • 1、提供健康检查的生命周期,组件开发者或者业务可以基于改能力,提供健康检查 API

设计逻辑

API

提供一个全局 HealthManager 提供基础健康检查 API 逻辑,HealthManager 不提供检查的时机逻辑,仅提供单次检查的方法调用。

API 设计如下:

interface HealthResult {
   status: boolean;
   reason: string;
   reasons: Array<{
      name: string;
      reason: string;
  }>;
}

interface HealthManager {
   getStatus(): HealthResult;
   setCheckTimeout(timeout: number): void;
}

同时,在 configuration 中新增 onHealthCheck 逻辑。

interface ILifeCycle {
  onHealthCheck(container?: IMidwayContainer): HealthResult;
}

在初始化时,HealthManager 加载所有组件、业务的 configuration,执行其 onHealthCheck 逻辑,如果不存在该方法,则跳过执行。

这里有两点:

  • 1、执行检查逻辑 并行执行
  • 2、需要考虑执行超时的情况,全局超时应该是一个比较宽松的时间,按照心跳逻辑,1s 较为合适

HealthResult 的数据结果

目前包含几个内容,status 成功或者失败,reason 最后一个报错的原因,reasons 记录所有的报错,包含模块名(namespace)和具体的 reason。

错误消息结构

{
   status: false,
   reason: 'redis 调用超时',
   reasons: [
      {
         "name": "redis",
         "reason": "redis 调用超时"
      }
   ]
}

设置全局检查超时时间

两种方式

  • 1、配置文件
  • 2、动态 API

配置文件设置。

// config.default
export default {
   core: {
      healthCheckTimeout: 2000,
  }
}

动态 API。

const healthManager = container.get(HealthManager);
healthManager.setCheckTimeout(2000);

使用

由于 HealthManager 仅有检查逻辑,但是没有执行逻辑。

  • 1、提供一个 health 组件,用于健康检查的逻辑,由业务自行引入
  • 2、上层模块直接使用 HealthManager ,自行执行 API 获取结果

HealthManager start 执行时机

HealthResult 接口是否需要增加一个时间戳 ( int or string) 属性,表示检查执行完毕时间。
对于并发(异步)执行的可能返回顺序不一定是固定的。

健康检查没有顺序的要求吧

健康检查是否可以直接提供给consul这些使用,这样类似consul这样的组件内部就不需要默认(或许就应该组件内自带?但是这里的健康状态是不全的)还是怎么样? 自定义或第三方组件要想接入检查应该如何做呢?

@flyingcrp 是需要每个组件去实现的,回头我给 redis 先加一个。

@flyingcrp 是需要每个组件去实现的,回头我给 redis 先加一个。

可以,我也想看看该如何用,能不能用于替换现在项目中健康检查

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.