nestjs集成grpc服务 - 指南

news/2025/11/30 13:21:32/文章来源:https://www.cnblogs.com/yangykaifa/p/19289130

h5打开以查看

一、基础配置方法

1. 项目结构准备

text

src/
├── grpc/
│   ├── user/
│   │   └── user.proto
│   ├── order/
│   │   └── order.proto
│   └── product/
│       └── product.proto
├── user/
│   ├── user.module.ts
│   └── user.service.ts
├── order/
│   ├── order.module.ts
│   └── order.service.ts
└── product/├── product.module.ts└── product.service.ts

2. 定义多个 Proto 文件

user.proto

protobuf

syntax = "proto3";package user;service UserService {rpc GetUser (UserRequest) returns (UserResponse) {}rpc CreateUser (CreateUserRequest) returns (UserResponse) {}
}message UserRequest {string id = 1;
}message CreateUserRequest {string name = 1;string email = 2;
}message UserResponse {string id = 1;string name = 2;string email = 3;
}

order.proto

protobuf

syntax = "proto3";package order;service OrderService {rpc GetOrder (OrderRequest) returns (OrderResponse) {}rpc CreateOrder (CreateOrderRequest) returns (OrderResponse) {}
}message OrderRequest {string id = 1;
}message CreateOrderRequest {string userId = 1;repeated string productIds = 2;
}message OrderResponse {string id = 1;string userId = 2;repeated string productIds = 3;string status = 4;
}

二、方式一:使用多个微服务客户端(推荐)

1. 配置多个 gRPC 客户端

app.module.ts

typescript

import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { join } from 'path';
import { UserModule } from './user/user.module';
import { OrderModule } from './order/order.module';@Module({imports: [ClientsModule.register([// 用户服务 gRPC 客户端{name: 'USER_PACKAGE',transport: Transport.GRPC,options: {package: 'user',protoPath: join(__dirname, 'grpc/user/user.proto'),url: 'localhost:50051', // 用户服务地址},},// 订单服务 gRPC 客户端{name: 'ORDER_PACKAGE',transport: Transport.GRPC,options: {package: 'order',protoPath: join(__dirname, 'grpc/order/order.proto'),url: 'localhost:50052', // 订单服务地址},},]),UserModule,OrderModule,],
})
export class AppModule {}

2. 创建用户服务

user/user.service.ts

typescript

import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { Observable } from 'rxjs';interface UserServiceClient {getUser(data: { id: string }): Observable;createUser(data: { name: string; email: string }): Observable;
}@Injectable()
export class UserService implements OnModuleInit {private userService: UserServiceClient;constructor(@Inject('USER_PACKAGE') private client: ClientGrpc) {}onModuleInit() {this.userService = this.client.getService('UserService');}async getUser(id: string) {return this.userService.getUser({ id });}async createUser(name: string, email: string) {return this.userService.createUser({ name, email });}
}

user/user.module.ts

typescript

import { Module } from '@nestjs/common';
import { UserService } from './user.service';@Module({providers: [UserService],exports: [UserService],
})
export class UserModule {}

3. 创建订单服务

order/order.service.ts

typescript

import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { Observable } from 'rxjs';interface OrderServiceClient {getOrder(data: { id: string }): Observable;createOrder(data: { userId: string; productIds: string[] }): Observable;
}@Injectable()
export class OrderService implements OnModuleInit {private orderService: OrderServiceClient;constructor(@Inject('ORDER_PACKAGE') private client: ClientGrpc) {}onModuleInit() {this.orderService = this.client.getService('OrderService');}async getOrder(id: string) {return this.orderService.getOrder({ id });}async createOrder(userId: string, productIds: string[]) {return this.orderService.createOrder({ userId, productIds });}
}

order/order.module.ts

typescript

import { Module } from '@nestjs/common';
import { OrderService } from './order.service';@Module({providers: [OrderService],exports: [OrderService],
})
export class OrderModule {}

4. 在控制器中使用多个服务

app.controller.ts

typescript

import { Controller, Get, Post, Body, Inject } from '@nestjs/common';
import { UserService } from './user/user.service';
import { OrderService } from './order/order.service';@Controller()
export class AppController {constructor(private readonly userService: UserService,private readonly orderService: OrderService,) {}@Get('user/:id')async getUser(@Param('id') id: string) {return this.userService.getUser(id);}@Post('order')async createOrder(@Body() createOrderDto: { userId: string; productIds: string[] }) {// 先验证用户是否存在const user = await this.userService.getUser(createOrderDto.userId);// 然后创建订单const order = await this.orderService.createOrder(createOrderDto.userId,createOrderDto.productIds,);return {user: user,order: order,};}
}

三、方式二:动态配置多个 gRPC 服务

1. 创建配置工厂

grpc/grpc.config.ts

typescript

import { Transport } from '@nestjs/microservices';
import { join } from 'path';export const grpcClientOptions = {user: {transport: Transport.GRPC,options: {package: 'user',protoPath: join(__dirname, 'user/user.proto'),url: 'localhost:50051',},},order: {transport: Transport.GRPC,options: {package: 'order',protoPath: join(__dirname, 'order/order.proto'),url: 'localhost:50052',},},product: {transport: Transport.GRPC,options: {package: 'product',protoPath: join(__dirname, 'product/product.proto'),url: 'localhost:50053',},},
};

2. 动态模块配置

grpc/grpc.module.ts

typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ClientsModule } from '@nestjs/microservices';
import { grpcClientOptions } from './grpc.config';@Module({})
export class GrpcModule {static register(clients: string[]): DynamicModule {const clientConfigs = clients.map(clientName => ({name: clientName.toUpperCase() + '_PACKAGE',...grpcClientOptions[clientName],}));return {module: GrpcModule,imports: [ClientsModule.register(clientConfigs)],exports: [ClientsModule],};}
}

3. 使用动态模块

app.module.ts

typescript

import { Module } from '@nestjs/common';
import { GrpcModule } from './grpc/grpc.module';
import { UserService } from './user/user.service';
import { OrderService } from './order/order.service';@Module({imports: [GrpcModule.register(['user', 'order', 'product']),// ... 其他模块],providers: [UserService, OrderService],
})
export class AppModule {}

四、方式三:使用配置文件和异步注册

1. 配置文件

config/grpc.config.ts

typescript

export default () => ({grpc: {services: {user: {package: 'user',protoPath: 'grpc/user/user.proto',url: process.env.USER_GRPC_URL || 'localhost:50051',},order: {package: 'order',protoPath: 'grpc/order/order.proto',url: process.env.ORDER_GRPC_URL || 'localhost:50052',},product: {package: 'product',protoPath: 'grpc/product/product.proto',url: process.env.PRODUCT_GRPC_URL || 'localhost:50053',},},},
});

2. 异步配置模块

grpc/grpc-client.module.ts

typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { join } from 'path';@Module({})
export class GrpcClientModule {static forRoot(serviceNames: string[]): DynamicModule {const clients = serviceNames.map(serviceName => ({name: `${serviceName.toUpperCase()}_PACKAGE`,useFactory: (configService: ConfigService) => {const serviceConfig = configService.get(`grpc.services.${serviceName}`);return {transport: Transport.GRPC,options: {package: serviceConfig.package,protoPath: join(__dirname, '..', serviceConfig.protoPath),url: serviceConfig.url,},};},inject: [ConfigService],}));return {module: GrpcClientModule,imports: [ClientsModule.registerAsync(clients),],exports: [ClientsModule],};}
}

3. 在主模块中使用

app.module.ts

typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { GrpcClientModule } from './grpc/grpc-client.module';
import configuration from './config/configuration';@Module({imports: [ConfigModule.forRoot({load: [configuration],}),GrpcClientModule.forRoot(['user', 'order', 'product']),// ... 其他模块],
})
export class AppModule {}

五、统一服务工厂模式

创建统一的 gRPC 服务工厂

grpc/grpc-factory.service.ts

typescript

import { Injectable, Inject, OnModuleInit } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { Observable } from 'rxjs';@Injectable()
export class GrpcServiceFactory implements OnModuleInit {private services = new Map();constructor(@Inject('USER_PACKAGE') private userClient: ClientGrpc,@Inject('ORDER_PACKAGE') private orderClient: ClientGrpc,@Inject('PRODUCT_PACKAGE') private productClient: ClientGrpc,) {}onModuleInit() {// 初始化所有服务this.services.set('user', this.userClient.getService('UserService'));this.services.set('order', this.orderClient.getService('OrderService'));this.services.set('product', this.productClient.getService('ProductService'));}getService(serviceName: string) {const service = this.services.get(serviceName);if (!service) {throw new Error(`gRPC service ${serviceName} not found`);}return service;}// 快捷方法getUserService() {return this.getService('user');}getOrderService() {return this.getService('order');}getProductService() {return this.getService('product');}
}

六、最佳实践建议

  1. 服务发现集成:在生产环境中,建议使用服务发现(如 Consul、Nacos)而不是硬编码 URL

  2. 连接管理:配置连接池和重试策略

  3. 错误处理:统一处理 gRPC 错误

  4. 超时设置:为每个服务设置合理的超时时间

  5. 健康检查:实现 gRPC 健康检查

typescript

// 示例:带超时和重试的配置
{transport: Transport.GRPC,options: {package: 'user',protoPath: join(__dirname, 'grpc/user/user.proto'),url: 'localhost:50051',maxRetries: 3,timeout: 5000, // 5秒超时keepalive: {keepaliveTimeMs: 30000,keepaliveTimeoutMs: 10000,},},
}

通过以上方式,可以在 NestJS 中灵活地调用多个 gRPC 服务的接口,并根据项目需求选择合适的配置方案。

h5打开以查看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/981858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0,1序列

import torch import torch.nn as nn import random ------------------------- 超参数 ------------------------- N_max = 10 # 最大 n 值(训练时用) input_size = 4 # 字符集大小:0, 1, , hidden…

提升开发效率的关键:Python 在工程应用中的五大实战技巧

在越来越多的工程项目中,Python 已经从辅助脚本工具,变成不少团队的“主力语言”。不仅是数据分析和自动化脚本,在测试开发、运维监控、设备联网、系统接口等场景里,Python 几乎都能找到自己的位置。 项目做得越多…

2025文艺演出资深机构TOP5权威推荐:甄选专业团队助力活

企业年会、品牌发布会、行业峰会等场景中,高质量文艺演出是提升活动质感、强化品牌记忆的核心载体。2024年活动策划市场数据显示,文艺演出服务需求年增速达38%,但超28%的客户投诉集中在节目同质化、现场效果失控、资…

2025年东北玻璃钢雕塑品牌商推荐:十大玻璃钢雕塑制造厂批量

在建筑装饰、商业美陈、文化景观等领域,玻璃钢雕塑凭借轻质高强、造型灵活、耐候性强的优势,成为空间美学与功能需求的重要载体。随着市场对定制化、批量化玻璃钢雕塑需求的激增,如何选择兼具设计实力、生产能力与交…

2025年十大专业的活动策划专业公司推荐,实力强的活动策划公

在企业品牌传播、用户链接的关键场景中,一场优质的活动是企业传递价值、撬动增长的核心载体。面对市场上良莠不齐的服务提供商,如何找到真正专业的活动策划专业公司?以下结合行业属性与服务能力,为你推荐2025年十大…

2025年黑龙江苯板雕刻制造商推荐:苯板雕刻优质供应商和生产

本榜单依托东北地区保温材料及造型定制领域的市场调研与真实客户反馈,深度筛选出五家标杆企业,为建筑装饰、商业美陈、婚庆会展等领域客户选型提供客观依据,助力精准匹配适配的服务伙伴。 TOP1 推荐:哈尔滨万嘉保温…

快懂百科创建代做公司有哪些,推荐一家能做快懂百科的公司

在AI搜索日益普及的当下,快懂百科作为重要的知识展示平台,成为企业建立线上权威形象、提升品牌认知度的关键载体。一份规范、完善的快懂百科词条,不仅能为消费者提供准确的品牌信息,更能凭借平台的公信力增强用户信…

2025年哈尔滨苯板立体雕刻加工厂/制造厂哪家更值得选?

为帮助建筑装饰、婚礼堂布置、影视道具制作等领域的客户精准锁定适配需求的苯板雕刻合作伙伴,避免因工艺粗糙、交付延迟导致项目损失,我们从雕刻精度(毫米级误差控制)、定制化能力(复杂造型还原度)、材料适配性(…

实用指南:实验十三 Z-buffer算法实验

实用指南:实验十三 Z-buffer算法实验2025-11-30 13:11 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !i…

升鲜宝供应链管理系统源代码---仓储式超市门店管理系统设计(一)

1.门店表(mall_shop) CREATE TABLE `mall_shop` (`id` bigint NOT NULL COMMENT 主键id,`shop_name` varchar(255) NOT NULL COMMENT 门店名称/客户名称,`shop_code` varchar(255) DEFAULT NULL COMMENT 门店编码,`sh…

RAG_查询重构与分发 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年全国信誉好的活动策划专业公司排行榜,售后完善、比较

为帮助企业高效锁定适配自身需求的活动策划合作伙伴,避免选型走弯路,我们从创意策划能力(如主题创新、流程设计)、执行落地水准(含设备搭建、现场控场)、全周期服务质量(覆盖前期调研到后期复盘)及真实客户口碑…

2025苯板雕刻加工厂TOP5权威推荐:苯板立体雕刻制造商哪

在建筑节能与装饰美学融合的趋势下,苯板雕刻作为兼具保温功能与艺术价值的关键材料,市场需求持续攀升。2024年数据显示,东北地区苯板雕刻市场规模同比增长32%,但35%的客户投诉集中在雕刻精度不足、交付延期、造型还…

java要记

ArrayList操作自定义对象进行removeAll()时,移除失效原因由于底层最用调用的是Object的equals()方法进行比较的,比较的是地址,两个对象地址当然是不同的了,移除自然会失败。解决方案:重写equals方法。【注意重写e…

关于python更换永久镜像源

在Python中更换永久镜像源主要有两种方式:pip镜像源和conda镜像源。以下是详细的配置方法: 1. pip镜像源配置 方法一:使用命令直接配置(推荐) # 清华镜像源 pip config set global.index-url https://pypi.tuna.t…

【C編程】多個.c文件聯編

W3C C tutorial將一個大型項目多個.c文件稱為模塊化編程。[1] 就是,多個.c文件互相調用。 方法是: 1)被調用方:定義.h和.c成對文件,.c要include .h文件 2) 調用方:include .h文件。 3) 聯合編譯:將兩個.c文件一…

2025年全国十大会议策划执行服务商排行榜,万贝上海文化传播

为助力企业高效匹配专业会议策划执行合作伙伴,避免选型踩坑,我们从创意策划能力、全流程落地执行力、资源整合覆盖度、客户口碑反馈及创新技术应用五大维度,对全国20+头部服务商展开深度评估,终筛选出2025年的十大…

2025年哈尔滨苯板雕刻来样定制公司排行榜,苯板雕刻品牌制造

为帮助建筑装饰、商业美陈、展会布景等领域客户精准锁定适配的苯板雕刻合作伙伴,避免因工艺不达标、交付延迟导致项目损失,我们从雕刻精度(毫米级误差控制)、定制响应速度(24小时需求反馈)、材料环保性(阻燃/防…

连接池的价值与风险——池化提升与资源枯竭的双刃剑,关键指标如何解读

连接池是现代应用架构中的基础设施,用好了是性能加速器,配置不当则成为系统崩溃的导火索在数据库应用系统中,连接管理是影响性能的关键因素之一。数据库连接池通过池化技术将昂贵的数据库连接进行复用,显著提升了系…

【大数据高并发核心场景实战】 数据持久化层 - 分表分库

我们在上一章讲到,查询分离的方案存在三大不足,其中一个就是:当主数据量越来越大时,写操作会越来越缓慢。这个问题该如何解决呢?可以考虑分表分库。今天我们会先介绍一下真实的业务场景,而后依次介绍拆分存储时如…