6月2日 01:25

NestJS 微服务怎么设计?Transport 层、消息模式和架构选型

NestJS 的微服务支持不是"把单体拆成微服务"的完整方案,而是提供了跨服务通信的 Transport 层。你可以用同样的 Controller/Service 写法,底层换成 Redis/RabbitMQ/Kafka/gRPC 通信,应用代码几乎不用改。

微服务模式 vs 单体

NestJS 应用默认是 HTTP 单体。改成微服务只需要换一个传输层:

typescript
// main.ts - HTTP 单体 const app = await NestFactory.create(AppModule); await app.listen(3000); // main.ts - 微服务 const app = await NestFactory.createMicroservice(AppModule, { transport: Transport.REDIS, options: { url: 'redis://localhost:6379' }, }); await app.listen();

微服务模式下,应用不再监听 HTTP 端口,而是通过消息队列接收请求。

通信模式

请求/响应(Request/Response)

和 HTTP 一样——发请求等响应。适合需要立即拿到结果的场景。

typescript
// 服务端 @MessagePattern('get_user') getUser(@Payload() id: string) { return this.usersService.findOne(id); } // 客户端 @Injectable() export class AppService { constructor(@Inject('USER_SERVICE') private client: ClientProxy) {} getUser(id: string) { return this.client.send('get_user', id); } }

send 返回 Observable,可以用 .toPromise()firstValueFrom() 转成 Promise。

事件驱动(Event-driven)

发出去不等响应——"fire and forget"。适合通知类场景(发邮件、写日志、更新缓存)。

typescript
// 发布者 this.client.emit('user_created', { userId: user.id }); // 订阅者 @EventPattern('user_created') handleUserCreated(@Payload() data: { userId: string }) { // 发送欢迎邮件、更新统计等 }

emit 不返回结果,订阅者可以有多个(广播模式)。请求/响应模式只会有一个服务响应。

Transport 选型

Transport适用场景特点
TCP开发/测试默认,零依赖
Redis简单生产环境Pub/Sub 模式,需要 Redis
RabbitMQ企业级消息确认、重试、路由
Kafka高吞吐日志流、事件溯源
gRPC高性能 RPC强类型、Protobuf

开发阶段用 TCP,不需要装任何中间件。生产环境看需求:简单场景用 Redis,复杂路由和消息确认用 RabbitMQ,日志和流处理用 Kafka。

混合模式:HTTP + 微服务

大部分现实应用需要一个 HTTP 入口 + 内部微服务通信。NestJS 支持混合模式:

typescript
// main.ts const app = await NestFactory.create(AppModule); const microservice = app.connectMicroservice({ transport: Transport.REDIS, options: { url: 'redis://localhost:6379' }, }); await app.startAllMicroservices(); await app.listen(3000);

这样应用同时监听 HTTP(给前端用)和 Redis 消息(给其他微服务用)。API Gateway 模式通常是这种——外部请求走 HTTP,内部服务间走消息队列。

什么时候该用微服务

不要因为"微服务是趋势"就拆。微服务引入的复杂度(部署、调试、数据一致性)对小团队是灾难。

适合微服务的信号:

  • 团队超过 10 人,需要独立部署不同模块
  • 某个模块有独立的伸缩需求(比如报表生成吃 CPU,需要单独扩容)
  • 不同模块的技术栈差异大(一个用 Node,一个用 Python)

不适合微服务的信号:

  • 3-5 人团队
  • 模块间数据高度耦合
  • 没有自动化部署和监控基础设施

大多数项目从模块化单体(Modular Monolith)开始更安全——NestJS 的 Module 本身就是天然的模块边界,等真正需要时再拆微服务,代码几乎不用改,只需要换 Transport。

标签:NestJS