🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 健康检查(Terminus) Nestjs Terminus集成提供了可读的/实时的健康检查。在复杂的后台设置中健康检查是非常重要的。简而言之,在web开发领域所说的健康检查通常由一系列特定地址组成,例如,https://my-website.com/health/readiness 通过一个服务,或者一个你的基础设施的一个部件(例如Kubernetes)来持续检查这个地址。依赖于向这一地址发出的`GET`请求返回的HTTP状态码,该服务会在收到“不健康”响应时采取行动。由于你的服务中对“健康”和“不健康”的定义可能有所不同,Nestjs Teminus支持一系列健康指示。 作为示例,如果你的服务器使用 MongoDB来存储数据,MongoDB是否正常运行就成了一个至关重要的信息。在这种情况下,你可以使用`MongooseHealthIndicator`。如果配置正常--按后续内容配置--你的健康检查地址将根据MongoDB是否运行来返回健康或者不健康HTTP状态码。 ### 入门 要开始使用 `@nestjs/terminus` ,我们需要安装所需的依赖项。 ```bash $ npm install --save @nestjs/terminus ``` ### 建立一个健康检查 健康检查表示健康指标的摘要。健康指示器执行服务检查,无论是否处于健康状态。 如果所有分配的健康指示符都已启动并正在运行,则运行状况检查为正。由于许多应用程序需要类似的健康指标,因此 `@nestjs/terminus` 提供了一组预定义的健康指标,例如: - `DNSHealthIndicator` - `TypeOrmHealthIndicator` - `MongooseHealthIndicator` - `MicroserviceHealthIndicator` - `GRPCHealthIndicator` - `MemoryHealthIndicator` - `DiskHealthIndicator` 要开始我们第一个健康检查,我们需要在`AppModule`引入`TerminusModule`。 > app.module.ts ```typescript import { Module } from '@nestjs/common'; import { TerminusModule } from '@nestjs/terminus'; @Module({ imports: [TerminusModule] }) export class AppModule { } ``` 我们的健康检查可以使用控制器来执行,使用`Nestjs CLI`可以快速配置: ```typescript $ nest generate controller health ``` > 强烈建议在你的应用程序中使用关机钩子。如果启用,Terminus将使用其生命周期事件。在[这里](https://docs.nestjs.com/fundamentals/lifecycle-events#application-shutdown)阅读更多关于关机钩子的内容。 ### DNS 健康检查 我们安装了`@nestjs/terminus`后,导入`TerminusModule`并创建一个新的控制器,我们就准备好创建一个新的健康检查了。 > health.controller.ts ```typescript @Controller('health') export class HealthController { constructor( private health: HealthCheckService, private dns: DNSHealthIndicator, ) {} @Get() @HealthCheck() check() { return this.health.check([ () => this.dns.pingCheck('nestjs-docs', 'https://docs.nestjs.com'), ]); } } ``` 我们的健康检查现在将发送一个Get请求到`https://docs.nestjs.com`地址,如果我们从该地址得到一个健康响应,我们的路径`http://localhost:3000/health`将在返回200状态码同时返回一个如下对象。 ```json { "status": "ok", "info": { "nestjs-docs": { "status": "up" } }, "error": {}, "details": { "nestjs-docs": { "status": "up" } } } ``` 该返回对象可以接口可以通过`@nestjs/terminus`包的`HealthCheckResult`接口来访问。 名称|内容|类型 --|--|-- status|如果任何健康检查失败了,状态将是'error'。如果NestJS应用即将关闭,但仍然能接受HTTP请求,状态检查将会返回'shutting_down'状态|'error'\|'ok'\|'shutting_down' info|对象包括每个状态是`up`(或者说健康)的健康指示器的信息|`object` error|对象包括每个状态是`down`(或者说不健康)的健康指示器的信息|`object` details|对象包括每个健康指示器的所有信息|`object` ### 自定义健康指标 在某些情况下,`@nestjs/terminus` 提供的预定义健康指标不会涵盖您的所有健康检查要求。 在这种情况下,您可以根据需要设置自定义运行状况指示器。 让我们开始创建一个代表我们自定义健康指标的服务。为了基本了解健康指标的结构,我们将创建一个示例 `DogHealthIndicator` 。如果每个 `Dog` 对象都具有 `goodboy` 类型,则此健康指示器应具有 `'up'` 状态,否则将抛出错误,然后健康指示器将被视为 `'down'` 。 > dog.health.ts ```typescript import { Injectable } from '@nestjs/common'; import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus'; export interface Dog { name: string; type: string; } @Injectable() export class DogHealthIndicator extends HealthIndicator { private dogs: Dog[] = [ { name: 'Fido', type: 'goodboy' }, { name: 'Rex', type: 'badboy' }, ]; async isHealthy(key: string): Promise<HealthIndicatorResult> { const badboys = this.dogs.filter(dog => dog.type === 'badboy'); const isHealthy = badboys.length === 0; const result = this.getStatus(key, isHealthy, { badboys: badboys.length }); if (isHealthy) { return result; } throw new HealthCheckError('Dogcheck failed', result); } } ``` 我们需要做的下一件事是将健康指标注册为提供者。 > app.module.ts ```typescript import { Module } from '@nestjs/common'; import { TerminusModule } from '@nestjs/terminus'; import { DogHealthIndicator } from './dog.health'; @Module({ controllers: [HealthController], imports: [TerminusModule], providers: [DogHealthIndicator] }) export class AppModule { } ``` > 在应用程序中,`DogHealthIndicator` 应该在一个单独的模块中提供,例如 `DogModule` ,然后由 `AppModule` 导入。 最后需要做的是在所需的运行状况检查端点中添加现在可用的运行状况指示器。 为此,我们返回到 `HealthController` 并将其实现到 `check` 函数中。 > health.controller.ts ```typescript import { HealthCheckService } from '@nestjs/terminus'; import { Injectable } from '@nestjs/common'; import { DogHealthIndicator } from './dog.health'; @Injectable() export class HealthController { constructor( private health: HealthCheckService, private dogHealthIndicator: DogHealthIndicator ) {} @Get() @HealthCheck() healthCheck() { return this.health.check([ async () => this.dogHealthIndicator.isHealthy('dog'), ]) } } ```