logologo
文档仓库
文档仓库
logologo
开始

概述

第一步
控制器
提供者
模块
中间件
异常过滤器
管道
守卫
拦截器
自定义装饰器

基础

自定义提供程序
异步提供者
动态模块
注入作用域
循环依赖
模块引用
懒加载模块
执行上下文
生命周期事件
发现服务
平台无关
单元测试

技术

配置
SQL
Mongo
验证
缓存
序列化
版本控制
任务调度
队列
日志
Cookies
事件
压缩
文件上传
文件流
HTTP 模块
Session
MVC
性能(Fastify)
SSE

安全

认证
授权
加密与哈希
Helmet
CORS
CSRF
速率限制

GraphQL

快速开始
解析器
变更
订阅
标量
指令
接口
联合与枚举
字段中间件
类型映射
插件
复杂度
扩展
CLI 插件
生成SDL
共享模型
其他功能
联邦

WebSocket

网关
异常过滤器
管道
守卫
拦截器
适配器

微服务

基础
Redis
MQTT
NATS
RabbitMQ
Kafka
gRPC
自定义传输
异常过滤器
管道
守卫
拦截器
部署
独立应用程序

CLI

概述
工作区
库
用法
脚本

OpenAPI

介绍
装饰器
类型映射
操作
其他特性
安全
类型与参数
CLI 插件

实用示例

REPL
CRUD生成器
SWC
Passport(认证)
热重载
MikroORM
TypeORM
Mongoose
Sequelize
路由模块
Swagger
健康检查
CQRS
Compodoc
Prisma
Sentry
静态资源
Commander
异步本地存储
Necord
套件(原Automock)

常见问题

Serverless
HTTP 适配器
长连接
全局前缀
原始请求体
混合应用
HTTPS & 多服务器
请求生命周期
错误

开发工具

概述
CI/CD
迁移指南
API参考(官方)

生态与案例

谁在用
精彩资源

支持

支持

社区

贡献者

最后更新于: 2025/11/18 02:11:37

上一页Swagger
下一页CQRS

#健康检查(Terminus)

Terminus 集成提供了就绪性/存活状态健康检查功能。在复杂的后端架构中,健康检查至关重要。简而言之,在 Web 开发领域,健康检查通常由一个特殊地址组成,例如 https://my-website.com/health/readiness 。您的服务或基础设施组件(如 Kubernetes)会持续检查该地址。根据对该地址 GET 请求返回的 HTTP 状态码,当收到"不健康"响应时,服务将采取相应措施。由于"健康"或"不健康"的定义因服务类型而异,Terminus 集成通过一组健康指标为您提供支持。

例如,如果您的 Web 服务器使用 MongoDB 存储数据,了解 MongoDB 是否仍在运行将是关键信息。在这种情况下,您可以使用 MongooseHealthIndicator。如果配置正确(稍后会详细介绍),您的健康检查地址将根据 MongoDB 是否运行返回健康或不健康的 HTTP 状态码。

#快速开始

要开始使用 @nestjs/terminus,我们需要先安装所需的依赖项。

$ npm install --save @nestjs/terminus

#设置健康检查

健康检查是对健康指标的汇总。健康指标会执行对服务的检查,判断其处于健康或不健康状态。当所有分配的健康指标都正常运行时,健康检查结果为通过。由于许多应用程序需要类似的健康指标,@nestjs/terminus 提供了一组预定义的指标,例如:

  • HttpHealthIndicator
  • TypeOrmHealthIndicator
  • MongooseHealthIndicator
  • SequelizeHealthIndicator
  • MikroOrmHealthIndicator
  • PrismaHealthIndicator
  • MicroserviceHealthIndicator
  • GRPCHealthIndicator
  • MemoryHealthIndicator
  • DiskHealthIndicator

要开始我们的第一个健康检查,让我们创建 HealthModule 模块,并在其 imports 数组中导入 TerminusModule。

提示

要使用 Nest CLI 创建该模块,只需执行 $ nest g module health 命令。

health.module.ts
import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';

@Module({
 imports: [TerminusModule]
})
export class HealthModule {}

我们的健康检查可以通过 控制器 来执行,使用 Nest CLI 可以轻松设置。

$ nest g controller health
信息

强烈建议在应用程序中启用关闭钩子。如果启用,Terminus 集成会利用此生命周期事件。了解更多关于关闭钩子的信息 请点击这里 。

#HTTP 健康检查

安装完 @nestjs/terminus、导入 TerminusModule 并创建新控制器后,我们就可以开始创建健康检查了。

HTTPHealthIndicator 需要 @nestjs/axios 包,请确保已安装:

$ npm i --save @nestjs/axios axios

现在我们可以设置 HealthController 了:

health.controller.ts
import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
 constructor(
   private health: HealthCheckService,
   private http: HttpHealthIndicator,
 ) {}

 @Get()
 @HealthCheck()
 check() {
   return this.health.check([
     () => this.http.pingCheck('nestjs-docs', './'),
   ]);
 }
}
health.module.ts
import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
 imports: [TerminusModule, HttpModule],
 controllers: [HealthController],
})
export class HealthModule {}

我们的健康检查将向 ../ 地址发送一个 _GET_ 请求。如果从该地址获得健康响应,我们在 http://localhost:3000/health` 的路由将返回以下对象,状态码为 200。

{
  "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
#检查特定的 HTTP 响应代码

在某些情况下,您可能需要检查特定条件并验证响应。例如,假设 https://my-external-service.com 返回响应代码 204。使用 HttpHealthIndicator.responseCheck 可以专门检查该响应代码,并将所有其他代码判定为不健康状态。

若返回的响应代码不是 204,则以下示例将被视为不健康。第三个参数要求提供一个(同步或异步)函数,该函数返回布尔值以判断响应是否健康(true)或不健康(false)。

health.controller.ts
// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
 return this.health.check([
   () =>
     this.http.responseCheck(
       'my-external-service',
       'https://my-external-service.com',
       (res) => res.status === 204,
     ),
 ]);
}

#TypeOrm 健康指标

Terminus 提供了将数据库检查添加到健康检查的能力。要开始使用此健康指标,您应查阅数据库章节并确保应用程序中的数据库连接已建立。

提示

在底层,TypeOrmHealthIndicator 仅执行一条常用于验证数据库是否存活的 SELECT 1 SQL 命令。若使用 Oracle 数据库,则会执行 SELECT 1 FROM DUAL。

health.controller.ts
@Controller('health')
export class HealthController {
 constructor(
   private health: HealthCheckService,
   private db: TypeOrmHealthIndicator,
 ) {}

 @Get()
 @HealthCheck()
 check() {
   return this.health.check([
     () => this.db.pingCheck('database'),
   ]);
 }
}

如果您的数据库可访问,现在通过 GET 请求访问 http://localhost:3000/health 时,应该会看到以下 JSON 结果:

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up"
    }
  }
}

如果您的应用使用多个数据库 ,需要将每个连接注入到 HealthController 中。然后就可以直接将连接引用传递给 TypeOrmHealthIndicator。

health.controller.ts
@Controller('health')
export class HealthController {
 constructor(
   private health: HealthCheckService,
   private db: TypeOrmHealthIndicator,
   @InjectConnection('albumsConnection')
   private albumsConnection: Connection,
   @InjectConnection()
   private defaultConnection: Connection,
 ) {}

 @Get()
 @HealthCheck()
 check() {
   return this.health.check([
     () => this.db.pingCheck('albums-database', { connection: this.albumsConnection }),
     () => this.db.pingCheck('database', { connection: this.defaultConnection }),
   ]);
 }
}

#磁盘健康指标

通过 DiskHealthIndicator 我们可以检查存储空间的使用情况。要开始使用,请确保注入 DiskHealthIndicator 将以下代码添加到你的 HealthController 中。以下示例检查路径 /(在 Windows 上可以使用 C:\\)的存储使用情况。如果使用量超过总存储空间的 50%,健康检查将返回不健康状态。

health.controller.ts
@Controller('health')
export class HealthController {
 constructor(
   private readonly health: HealthCheckService,
   private readonly disk: DiskHealthIndicator,
 ) {}

 @Get()
 @HealthCheck()
 check() {
   return this.health.check([
     () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
   ]);
 }
}

通过 DiskHealthIndicator.checkStorage 函数,你还可以检查固定大小的存储空间。以下示例中,如果路径 /my-app/ 超过 250GB,健康状态将变为不健康。

health.controller.ts
// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
 return this.health.check([
   () => this.disk.checkStorage('storage', {  path: '/', threshold: 250 * 1024 * 1024 * 1024, })
 ]);
}

#内存健康指标

为确保你的进程不超过特定内存限制,可以使用 MemoryHealthIndicator。以下示例可用于检查进程的堆内存使用情况。

提示

堆是内存中动态分配内存(即通过 malloc 分配的内存)所在的区域。从堆中分配的内存将保持分配状态,直到发生以下情况之一:

  • 内存被释放
  • 程序终止
health.controller.ts
@Controller('health')
export class HealthController {
 constructor(
   private health: HealthCheckService,
   private memory: MemoryHealthIndicator,
 ) {}

 @Get()
 @HealthCheck()
 check() {
   return this.health.check([
     () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
   ]);
 }
}

您还可以使用 MemoryHealthIndicator.checkRSS 来验证进程的内存 RSS。如果您的进程确实分配了超过 150MB 的内存,此示例将返回一个异常响应码。

提示

RSS(常驻内存集)用于显示分配给该进程且驻留在 RAM 中的内存量。它不包括被交换出去的内存,但包含来自共享库的内存(只要这些库的页面实际存在于内存中),同时包含所有栈和堆内存。

health.controller.ts
// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
 return this.health.check([
   () => this.memory.checkRSS('memory_rss', 150 * 1024 * 1024),
 ]);
}

#自定义健康指标

在某些情况下,@nestjs/terminus 提供的预定义健康指标无法满足您的所有健康检查需求。此时,您可以根据需要设置自定义健康指标。

让我们从创建一个代表自定义指标的服务开始。为了基本了解指标的结构,我们将创建一个示例 DogHealthIndicator。当每个 Dog 对象的类型为 'goodboy' 时,该服务应处于 'up' 状态。如果条件不满足,则应抛出错误。

dog.health.ts
import { Injectable } from '@nestjs/common';
import { HealthIndicatorService } from '@nestjs/terminus';

export interface Dog {
 name: string;
 type: string;
}

@Injectable()
export class DogHealthIndicator {
 constructor(
   private readonly healthIndicatorService: HealthIndicatorService
 ) {}

 private dogs: Dog[] = [
   { name: 'Fido', type: 'goodboy' },
   { name: 'Rex', type: 'badboy' },
 ];

 async isHealthy(key: string){
   const indicator = this.healthIndicatorService.check(key);
   const badboys = this.dogs.filter(dog => dog.type === 'badboy');
   const isHealthy = badboys.length === 0;

   if (!isHealthy) {
     return indicator.down({ badboys: badboys.length });
   }

   return indicator.up();
 }
}

接下来我们需要将健康指标注册为提供者。

health.module.ts
import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { DogHealthIndicator } from './dog.health';

@Module({
 controllers: [HealthController],
 imports: [TerminusModule],
 providers: [DogHealthIndicator]
})
export class HealthModule { }
提示

在实际应用中,DogHealthIndicator 应该在一个单独的模块中提供,例如 DogModule,然后由 HealthModule 导入。

最后一步是将现已可用的健康指标添加到所需的健康检查端点。为此,我们回到 HealthController 并将其添加到我们的 check 函数中。

health.controller.ts
import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Injectable, Dependencies, Get } 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([
     () => this.dogHealthIndicator.isHealthy('dog'),
   ])
 }
}

#日志记录

Terminus 仅记录错误消息,例如当健康检查失败时。通过 TerminusModule.forRoot() 方法,您可以更好地控制错误记录方式,甚至完全接管日志记录本身。

在本节中,我们将指导您如何创建自定义日志记录器 TerminusLogger。该日志记录器扩展了内置日志功能,因此您可以选择性地覆盖日志记录器的特定部分

提示

如需了解更多关于 NestJS 中自定义日志记录器的信息, 请点击此处阅读更多内容 。

terminus-logger.service.ts
import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class TerminusLogger extends ConsoleLogger {
 error(message: any, stack?: string, context?: string): void;
 error(message: any, ...optionalParams: any[]): void;
 error(
   message: unknown,
   stack?: unknown,
   context?: unknown,
   ...rest: unknown[]
 ): void {
   // Overwrite here how error messages should be logged
 }
}

创建自定义日志记录器后,您只需将其传入 TerminusModule.forRoot() 即可,如下所示。

health.module.ts
@Module({
imports: [
 TerminusModule.forRoot({
   logger: TerminusLogger,
 }),
],
})
export class HealthModule {}

若要完全抑制来自 Terminus 的所有日志消息(包括错误消息),请按如下方式配置 Terminus。

health.module.ts
@Module({
imports: [
 TerminusModule.forRoot({
   logger: false,
 }),
],
})
export class HealthModule {}

Terminus 允许您配置健康检查错误在日志中的显示方式。

错误日志样式描述示例
json(默认)在出现错误时以 JSON 对象形式打印健康检查结果摘要
pretty在格式化框内打印健康检查结果摘要,并高亮显示成功/错误结果

您可以通过如下代码片段所示的 errorLogStyle 配置选项来更改日志样式

health.module.ts
@Module({
 imports: [
   TerminusModule.forRoot({
     errorLogStyle: 'pretty',
   }),
 ]
})
export class HealthModule {}

#优雅停机超时时间

如果您的应用程序需要延迟关闭过程,Terminus 可以为您处理。这一设置在配合 Kubernetes 等编排器使用时尤为有益。通过将延迟时间设置为略长于就绪检查间隔,您可以在关闭容器时实现零停机。

health.module.ts
@Module({
 imports: [
   TerminusModule.forRoot({
     gracefulShutdownTimeoutMs: 1000,
   }),
 ]
})
export class HealthModule {}

#更多示例

更多工作示例可在此查看。