2. NestJS 微服务基础:创建微服务应用、传输层与通信模式
在构建分布式系统时,微服务架构通过将单一应用拆分为多个独立部署的服务,实现了高内聚、低耦合。NestJS 作为一款渐进式 Node.js 框架,原生提供了强大的微服务支持,允许开发者使用统一的编程模型构建异构系统。本章将深入讲解 NestJS 微服务的核心概念,包括如何创建微服务应用、四种主流传输层的特性对比,以及三种基本的微服务通信模式。
2.1 创建 NestJS 微服务应用
NestJS 微服务应用与常规 HTTP 应用在架构上有所不同。微服务应用通常不直接监听 HTTP 端口,而是通过特定的传输层监听消息。创建过程分为两步:创建微服务实例与配置传输层策略。
2.1.1 基础创建流程
首先,使用 @nestjs/microservices 包中的 MicroserviceOptions 接口定义传输层选项。以下示例展示了如何创建一个基于 TCP 传输的微服务应用:
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
options: {
host: '127.0.0.1',
port: 3001,
},
},
);
await app.listen();
}
bootstrap();
关键点说明:
- NestFactory.createMicroservice:创建微服务实例,而非 HTTP 实例。
- Transport.TCP:指定传输层协议为 TCP。
- options:配置传输层参数,如主机地址和端口。
2.1.2 混合应用模式
在实际项目中,微服务节点往往需要同时提供 HTTP API 和内部微服务通信能力。NestJS 支持混合应用模式,即一个应用同时监听 HTTP 端口和微服务传输层端口:
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 连接微服务传输层
app.connectMicroservice<MicroserviceOptions>({
transport: Transport.TCP,
options: { port: 3001 },
});
await app.startAllMicroservices();
await app.listen(3000);
}
bootstrap();
2.2 传输层:TCP、Redis、RabbitMQ、Kafka
传输层是微服务通信的基石,决定了消息如何在不同服务之间传递。NestJS 内置支持四种主流传输层:TCP、Redis、RabbitMQ 和 Kafka。每种传输层都有其适用场景和性能特征。
2.2.1 传输层对比
| 传输层 | 通信模型 | 消息持久化 | 适用场景 | 性能 |
|---|---|---|---|---|
| TCP | 点对点 | 无 | 开发环境、简单内部服务 | 高(低延迟) |
| Redis | 发布/订阅 | 无(默认) | 轻量级广播、缓存同步 | 高 |
| RabbitMQ | 队列 + 交换器 | 支持 | 任务队列、可靠消息传递 | 中高 |
| Kafka | 分区日志 | 支持(日志持久化) | 事件流、日志聚合、大数据 | 高(吞吐量优先) |
2.2.2 各传输层配置示例
Redis 传输层配置:
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.REDIS,
options: {
host: 'localhost',
port: 6379,
},
},
);
RabbitMQ 传输层配置:
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.RMQ,
options: {
urls: ['amqp://localhost:5672'],
queue: 'user-service-queue',
queueOptions: {
durable: true,
},
},
},
);
Kafka 传输层配置:
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.KAFKA,
options: {
client: {
brokers: ['localhost:9092'],
},
consumer: {
groupId: 'user-consumer-group',
},
},
},
);
2.3 微服务通信模式
NestJS 微服务支持三种核心通信模式:请求-响应、基于消息的事件驱动、以及流式处理。理解这些模式是设计微服务交互的基础。
2.3.1 请求-响应模式(Request-Response)
这是最常用的同步通信模式。客户端发送请求并等待服务端响应。在 NestJS 中,通过 @MessagePattern() 装饰器定义消息处理程序。
服务端定义:
import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
@Controller()
export class UserController {
@MessagePattern({ cmd: 'get_user' })
getUser(data: { id: number }): any {
// 模拟查询用户
return { id: data.id, name: 'Alice' };
}
}
客户端调用:
import { Injectable, Inject } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
@Injectable()
export class UserService {
constructor(@Inject('USER_SERVICE') private client: ClientProxy) {}
async getUser(id: number) {
return this.client.send({ cmd: 'get_user' }, { id }).toPromise();
}
}
2.3.2 事件驱动模式(Event-Driven)
事件驱动模式采用发布/订阅机制,发送方发布事件,接收方异步处理。使用 @EventPattern() 装饰器定义事件处理程序。
事件发布者:
this.client.emit('user_created', { userId: 1, email: 'alice@example.com' });
事件消费者:
import { Controller } from '@nestjs/common';
import { EventPattern } from '@nestjs/microservices';
@Controller()
export class NotificationController {
@EventPattern('user_created')
handleUserCreated(data: { userId: number; email: string }) {
// 发送欢迎邮件
console.log(`Sending welcome email to ${data.email}`);
}
}
2.3.3 流式处理模式(Streaming)
流式处理适用于处理大量连续数据,如日志收集或实时指标。NestJS 通过 RxJS Observable 支持流式响应。
import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';
import { Observable, interval } from 'rxjs';
import { map } from 'rxjs/operators';
@Controller()
export class MetricsController {
@MessagePattern({ cmd: 'stream_metrics' })
streamMetrics(): Observable<any> {
return interval(1000).pipe(
map(() => ({ timestamp: Date.now(), cpu: Math.random() * 100 })),
);
}
}
2.4 通信模式对比与选择
| 模式 | 同步/异步 | 耦合度 | 典型场景 |
|---|---|---|---|
| 请求-响应 | 同步 | 高(调用方依赖响应) | 查询用户信息、订单状态 |
| 事件驱动 | 异步 | 低(发布者不关心消费者) | 用户注册通知、库存更新 |
| 流式处理 | 异步 | 中(持续连接) | 实时监控、日志流 |
2.5 本章小结
本章介绍了 NestJS 微服务的基础知识,包括如何创建微服务应用、四种传输层的配置与对比,以及三种核心通信模式。掌握这些基础是后续学习熔断降级和依赖反转设计的前提。在实际项目中,应根据业务需求、性能要求和可靠性目标选择合适的传输层和通信模式组合。