2. NestJS 微服务基础回顾:核心概念、通信模式与模块划分

在构建支付订单微服务系统之前,需要先夯实 NestJS 微服务的基础知识。本章将回顾 NestJS 的核心概念、两种主流的微服务通信模式(TCP 与 RabbitMQ),并基于支付订单业务场景进行服务模块的合理划分。

2.1 NestJS 核心概念速览

NestJS 的微服务架构并非重新发明轮子,而是在其核心的模块化、依赖注入、装饰器体系之上,增加了传输层的抽象。以下四个概念是理解后续所有内容的关键:

概念 作用 微服务中的角色
Module(模块) 组织代码的边界,通过 @Module() 声明 每个微服务本身是一个根模块,内部按业务拆分子模块
Controller(控制器) 处理入站请求(HTTP / 消息 / RPC) 在微服务中,控制器处理来自传输层的消息模式
Provider(提供者) 封装业务逻辑,通过依赖注入使用 Service、Repository、ClientProxy 等均作为提供者注册
ClientProxy(客户端代理) 微服务间通信的客户端抽象 通过 @Client() 或 ClientProxyFactory 创建,发送消息到其他服务
提示: NestJS 微服务应用与普通 HTTP 应用在启动方式上几乎一致,区别仅在于使用 createMicroservice() 替代 create(),并指定传输策略(Transport Strategy)。

2.2 微服务通信模式:TCP 与 RabbitMQ

NestJS 支持多种传输层,本课程重点使用 TCP 和 RabbitMQ 两种模式。它们分别适用于不同的场景:

  • TCP 模式: 基于 Node.js 内置的 net 模块,采用自定义协议(JSON 序列化)。适合内部直连、低延迟、小规模集群的场景。
  • RabbitMQ 模式: 基于 AMQP 协议,通过消息队列解耦。适合需要削峰填谷、广播、异步处理、高可靠性的生产环境。

2.2.1 通信模式对比

维度 TCP 模式 RabbitMQ 模式
通信方式 点对点直连 通过交换机/队列中转
消息持久化 不支持(内存直连) 支持(磁盘持久化)
消费者数量 一对一 一对多(竞争消费或发布订阅)
适用场景 同步 RPC、内部管理接口 异步事件、订单状态变更、支付回调
NestJS 装饰器 @MessagePattern() @MessagePattern() / @EventPattern()

2.2.2 两种模式的代码骨架对比

以下代码展示了 TCP 与 RabbitMQ 在服务端启动时的核心差异:

// TCP 模式启动(main.ts)
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: '0.0.0.0',
        port: 3001,
      },
    },
  );
  await app.listen();
}
bootstrap();
// RabbitMQ 模式启动(main.ts)
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.RMQ,
      options: {
        urls: ['amqp://user:password@localhost:5672'],
        queue: 'payment_queue',
        queueOptions: {
          durable: true,
        },
      },
    },
  );
  await app.listen();
}
bootstrap();
注意: 在 RabbitMQ 模式下,如果使用 @EventPattern(),发送方不需要等待响应,适合异步事件;如果使用 @MessagePattern(),发送方会等待响应,适合 RPC 调用。两种模式在同一个服务中可以混合使用。

2.3 支付订单服务模块划分

基于微服务拆分原则,我们将支付订单系统划分为四个独立的微服务模块。每个模块拥有独立的数据库、独立的部署单元,通过 TCP 或 RabbitMQ 进行通信。

2.3.1 模块划分总览

微服务名称 核心职责 主要数据表 通信方式
订单服务 订单创建、状态流转、超时取消 orders, order_items TCP(同步 RPC)
支付服务 支付请求、渠道对接、退款处理 payments, refunds RabbitMQ(异步事件)
账户服务 用户余额、冻结、流水记录 accounts, transactions TCP(同步 RPC)
通知服务 支付结果通知、短信/邮件推送 notifications RabbitMQ(事件订阅)

2.3.2 模块间通信关系图

下图展示了四个微服务之间的调用关系与消息流向:

支付订单微服务模块通信关系 订单服务 TCP 同步 RPC 支付服务 RabbitMQ 异步 账户服务 TCP 同步 RPC 通知服务 RabbitMQ 事件订阅 RabbitMQ 支付事件 / 通知事件 创建支付 扣款/退款 支付结果 推送通知 查询余额 实线:同步 RPC 虚线:异步事件

2.4 模块划分设计原则

在划分上述四个服务时,我们遵循了以下三条核心原则:

  1. 按业务能力拆分: 每个服务对应一个明确的业务领域(订单、支付、账户、通知),避免跨领域的数据耦合。
  2. 按通信模式拆分: 需要同步响应的操作(如查询余额、创建订单)使用 TCP;需要异步解耦的操作(如支付结果通知)使用 RabbitMQ。
  3. 按数据边界拆分: 每个服务拥有独立的数据库,服务之间不直接访问对方的数据库,只能通过 API 或消息进行数据交换。
关键决策: 支付服务作为整个系统的核心枢纽,同时承担了同步 RPC(接收订单服务的支付请求)和异步事件(向 MQ 发送支付结果)两种角色。这种混合模式在实际生产环境中非常常见,也是后续链路追踪需要重点覆盖的边界。

2.5 本章小结

通过本章回顾,我们明确了以下内容:

  • NestJS 微服务的核心概念(Module、Controller、Provider、ClientProxy)及其在微服务中的角色。
  • TCP 与 RabbitMQ 两种通信模式的区别、适用场景及代码实现差异。
  • 支付订单系统的四个微服务模块(订单、支付、账户、通知)的职责划分与通信关系。