活动介绍

利用NestJS构建可扩展微服务

立即解锁
发布时间: 2025-08-14 01:10:35 阅读量: 3 订阅数: 13
PDF

NestJS可扩展应用开发实战

### 利用 NestJS 构建可扩展微服务 #### 1. NestJS 微服务包概述 NestJS 的 `@nestjs/microservices` 包具有以下核心优势: - **弹性通信**:内置处理服务中断的策略,如重试和退避机制,确保服务在故障条件下保持健壮。 - **与其他模块集成**:该包旨在与其他 NestJS 模块和谐协作,保证安全和配置等方面在所有服务中得到一致管理。 下面通过一个简单示例展示如何使用该模块实现微服务间的通信。假设我们有一个服务需要异步处理用户数据: ```typescript import { Controller } from '@nestjs/common'; import { MessagePattern, Payload } from '@nestjs/microservices'; @Controller() export class UserDataProcessor { @MessagePattern({ cmd: 'process_user_data'}) async processUserData(@Payload() data: any) { // Logic to process user data console.log('Processing user data:', data); } } ``` 在这个示例中,`@MessagePattern` 装饰器修饰 `processUserData` 方法,用于监听 `{ cmd: 'process_user_data'}` 模式的消息。每当接收到该主题的消息时,该方法将被触发,并携带消息负载。 #### 2. 搭建单仓库结构 在深入微服务通信之前,我们需要将当前项目结构转换为单仓库(mono repo)结构。步骤如下: 1. 使用 `nest-cli` 生成多个应用。在项目根目录运行以下命令: ```bash $ nest generate app order # then $ nest generate app inventory ``` 2. 运行上述命令后,项目结构会发生如下变化: - 项目根目录下新增 `apps/` 文件夹。 - 现有项目位于 `/apps/original-application-name` 下(这里 `original-application-name` 为 `microservices-sample`)。 - `package.json` 文件中的部分命令更新,例如 `start:prod` 命令变为 `"start:prod": "node dist/apps/microservices-sample/main"`,这意味着 `microservices-sample` 项目将作为入口点,即 API 网关。 - `nest-cli.json` 文件更新如下: ```json { "$schema": "<https://json.schemastore.org/nest-cli>", "collection": "@nestjs/schematics", "sourceRoot": "apps/microservices-sample/src", "compilerOptions": { "deleteOutDir": true, "webpack": true, "tsConfigPath": "apps/microservices-sample/tsconfig.app.json" }, "monorepo": true, "root": "apps/microservices-sample", "projects": { "microservices-sample": { "type": "application", "root": "apps/microservices-sample", "entryFile": "main", "sourceRoot": "apps/microservices-sample/src", "compilerOptions": { "tsConfigPath": "apps/microservices-sample/tsconfig.app.json" } }, "order": { "type": "application", "root": "apps/order", "entryFile": "main", "sourceRoot": "apps/order/src", "compilerOptions": { "tsConfigPath": "apps/order/tsconfig.app.json" } }, "inventory": { "type": "application", "root": "apps/inventory", "entryFile": "main", "sourceRoot": "apps/inventory/src", "compilerOptions": { "tsConfigPath": "apps/inventory/tsconfig.app.json" } } } } ``` #### 3. 应用关键特性 为了简化操作,我们将构建一个简单的订单管理系统,其核心功能如下: | 步骤 | 描述 | | ---- | ---- | | 1 | 当用户下单时,向订单服务发送包含订单信息(如购买用户、产品、总价)的 POST 请求。 | | 2 | 订单服务接收到请求后,发起订单创建操作(可视为数据库事务),并发出 `order_created` 主题的事件,该事件将由库存服务消费。 | | 3 | 库存服务接收到 `order_created` 事件后,检查库存中是否有足够的产品。如果有,通过 `order_processed` 主题的事件更新库存水平和订单状态;如果没有,则通过相同主题但不同负载的事件拒绝订单创建,订单服务将相应更新订单状态。 | #### 4. 构建订单服务 ##### 4.1 订单服务技术要求 - 监听 `/orders` 端点的 HTTP POST 请求以创建新订单。 - 订单创建后发出事件,由库存服务处理。 - 监听来自库存服务的事件,并相应更新订单状态。 ##### 4.2 实现订单服务逻辑 1. 更新 `apps/order/src/main.ts` 文件: ```typescript import { NestFactory } from '@nestjs/core'; import { OrderModule } from './order.module'; async function bootstrap() { const app = await NestFactory.create(OrderModule); // to connect to the microservices linked to the order // service app.startAllMicroservices(); await app.listen(3001); } bootstrap(); ``` 2. 创建 `apps/order/entities/order.entity.ts` 文件,定义订单实体: ```typescript export enum OrderStatus { PENDING = 'Pending', COMPLETED = 'Completed', CANCELLED = 'Cancelled', } export class Order { id: string; name: string; product: string; price: number; status: OrderStatus; quantity: number; } ``` 3. 在 `OrderModule` 中注册库存服务: ```typescript import { Module } from '@nestjs/common'; import { ClientsModule, Transport } from '@nestjs/microservices'; import { OrderController } from './order.controller'; import { OrderService } from './order.service'; @Module({ imports: [ ClientsModule.register([ { name: 'INVENTORY_SERVICE', transport: Transport.TCP, options: { port: 8002, }, }, ]), ], controllers: [OrderController], providers: [OrderService], }) export class OrderModule {} ``` 4. 实现订单创建业务逻辑: ```typescript // order/order.service.ts import { Inject, Injectable } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; import { Order, OrderStatus } from './entities/order.entity'; import { CreateOrderInput } from './dto/create-order.dto'; @Injectable() export class OrderService { constructor( @Inject('INVENTORY_SERVICE') private inventoryClient: ClientProxy, ) {} // in memory storage - for demo purposes private orders: Order[] = []; createOrder(createOrderInput: CreateOrderInput): Order { const order = { ```
corwn 最低0.47元/天 解锁专栏
赠100次下载
继续阅读 点击查看下一篇
profit 400次 会员资源下载次数
profit 300万+ 优质博客文章
profit 1000万+ 优质下载资源
profit 1000万+ 优质文库回答
复制全文

相关推荐

李_涛

知名公司架构师
拥有多年在大型科技公司的工作经验,曾在多个大厂担任技术主管和架构师一职。擅长设计和开发高效稳定的后端系统,熟练掌握多种后端开发语言和框架,包括Java、Python、Spring、Django等。精通关系型数据库和NoSQL数据库的设计和优化,能够有效地处理海量数据和复杂查询。
最低0.47元/天 解锁专栏
赠100次下载
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
千万级 优质文库回答免费看