1. 课程导学与前置知识:NestJS 核心概念回顾
在正式进入熔断降级与接口通信调优之前,我们需要快速回顾 NestJS 的核心构建块。这些概念将贯穿整个课程,是理解后续高级主题的基础。本章将聚焦于依赖注入、模块化、装饰器、管道、守卫和拦截器,并通过一个内联 SVG 架构图展示它们之间的协作关系。
1.1 NestJS 核心架构概览
NestJS 的架构围绕 模块 组织,每个模块封装一组相关的功能。请求从控制器进入,经过守卫、管道、拦截器组成的处理链,最终到达服务层。下图展示了这一核心流程:
1.2 依赖注入与模块化
依赖注入是 NestJS 的基石。它通过 @Injectable() 装饰器标记提供者,并在构造函数中自动注入依赖。模块使用 @Module() 装饰器组织代码,控制提供者、控制器和导入导出的范围。
| 概念 | 装饰器 | 作用 | 示例 |
|---|---|---|---|
| 提供者 | @Injectable() |
标记类可被依赖注入容器管理 | @Injectable() export class UserService {} |
| 模块 | @Module() |
组织相关组件,定义作用域 | @Module({ imports: [], controllers: [], providers: [] }) |
| 控制器 | @Controller() |
定义路由和请求处理入口 | @Controller('users') export class UserController {} |
💡 关键点: 依赖注入使得服务之间的耦合度降低,便于单元测试和模块替换。在熔断降级场景中,我们可以通过注入不同的策略实现(如直接返回降级结果或调用备用服务)来动态切换行为。
1.3 装饰器:元数据与行为注入
装饰器是 NestJS 实现声明式编程的核心工具。除了框架内置的装饰器,我们还可以使用 @SetMetadata() 自定义元数据,结合守卫或拦截器实现细粒度的权限控制或熔断策略。
// 自定义装饰器示例:标记需要熔断保护的路由
import { SetMetadata } from '@nestjs/common';
export const CIRCUIT_BREAKER_KEY = 'circuit_breaker';
export const CircuitBreaker = (threshold: number) =>
SetMetadata(CIRCUIT_BREAKER_KEY, { threshold });
1.4 管道:数据验证与转换
管道负责对控制器方法参数进行验证和转换。NestJS 内置了 ValidationPipe、ParseIntPipe 等,也支持自定义管道。在接口通信调优中,管道可以提前过滤无效请求,减少下游服务的压力。
- 验证管道:结合 class-validator 装饰器,自动校验请求体。
- 转换管道:将字符串参数转换为数字、布尔值等类型。
- 自定义管道:实现
PipeTransform接口,编写业务逻辑。
// 自定义验证管道示例
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common';
@Injectable()
export class PositiveIntPipe implements PipeTransform {
transform(value: number) {
if (value <= 0) {
throw new BadRequestException('Value must be a positive integer');
}
return value;
}
}
1.5 守卫:请求授权与准入控制
守卫决定请求是否能够到达路由处理器。它基于 CanActivate 接口,返回 true 或 false。守卫常用于身份验证和权限检查,也可以用于实现基于请求特征的熔断前置判断。
| 守卫类型 | 典型用途 | 执行时机 |
|---|---|---|
| AuthGuard | 验证 JWT Token 或 Session | 所有受保护路由之前 |
| RolesGuard | 检查用户角色是否匹配 | 路由处理之前 |
| 自定义守卫 | 基于请求头、IP、频率等条件 | 按需绑定 |
📌 实战提示: 在熔断降级场景中,守卫可以结合 Redis 或内存状态,快速拒绝已经达到熔断阈值的请求,避免请求进入后续处理链。
1.6 拦截器:AOP 切面编程的核心
拦截器是 NestJS 实现面向切面编程(AOP)的关键。它可以在方法执行前后添加逻辑,非常适合实现日志记录、缓存、熔断降级、超时控制等横切关注点。
// 拦截器示例:记录请求耗时
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const now = Date.now();
return next.handle().pipe(
tap(() => console.log(`Request took ${Date.now() - now}ms`))
);
}
}
1.7 核心概念对比总结
| 组件 | 职责 | 执行顺序 | 熔断降级中的角色 |
|---|---|---|---|
| 守卫 | 请求准入控制 | 最先执行 | 快速拒绝熔断请求 |
| 管道 | 参数验证与转换 | 守卫之后 | 过滤无效参数,减少下游压力 |
| 拦截器 | 方法执行前后增强 | 管道之后,控制器前后 | 实现熔断逻辑、超时控制、降级响应 |
| 装饰器 | 元数据标记 | 编译时 | 标记熔断策略配置 |