NestJS使用gRPC实现微服务通信
代码仓库地址:https://github.com/zeng-jc/rpc-grpc-practice
1.1 基本概念
gRPC 基于 Protocol Buffers(protobuf)作为接口定义语言(IDL),意味着你可以使用 protobuf 来定义你的服务接口,gRPC生成的代码可以用于多种语言(C++, Java, Python, Go, C#, Ruby, Node.js),所以使用gRPC就能实现跨语言之间进行微服务通信。
gRPC 基于根据可远程调用的功能(方法)定义服务的概念。 对于每个方法,参数和返回类型需要在.proto文件中定义。
1.2 提供者中proto配置
首先创建创建一个grpc-provider的服务(启动服务说明:npm run start:dev grpc-provider)
nest generate app grpc-provider
接着上一章我们需要继续安装grpc包
接着上一章我们需要继续安装grpc包
npm i --save @grpc/grpc-js @grpc/proto-loader
然后在main.ts中做出如下配置
import { NestFactory } from '@nestjs/core';
import { GrpcProviderModule } from './grpc-provider.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';
async function bootstrap() {const app = await NestFactory.createMicroservice<MicroserviceOptions>(GrpcProviderModule,{// 传输方式GRPCtransport: Transport.GRPC,options: {// proto包名package: 'hero',// proto包的地址protoPath: join(__dirname, 'proto/hero.proto'),// 你的服务地址url: '127.0.0.1:3001',},},);await app.listen();
}
bootstrap();
配置完成后此时你还不能立即启动项目,因为nest-cli中还没配置proto文件,所以nestjs并不会对proto文件进行编译。接下来是对nest-cli.json的配置
{"compilerOptions": {"assets": ["**/*.proto"],"watchAssets": true},
}
此时启动项目还是会报错的,因为我们还没有创建proto文件和内容的写入,如下是对proto文件的配置
// hero/hero.proto
syntax = "proto3"; //表示proto使用的语法
package hero; //proto包名
// 定义服务HeroesService
service HeroesService {// FindOne方法rpc FindOne (HeroById) returns (Hero) {}
}
// FindOne方法参数配置
message HeroById {int32 id = 1;
}
// FindOne方法返回值配置
message Hero {int32 id = 1;string name = 2;
}
1.3 grpc提供者服务实现
我们需要在src目录下先创建heroes资源,没有必要通过nest g res heroes快捷指令创建。创建heroes目录后再创建heroes.controller.ts和heroes.module.ts即可,heroes.module.ts记得在grpc-provider.module.ts导入。
import { Controller } from '@nestjs/common';
import { GrpcMethod } from '@nestjs/microservices';
import { Metadata, ServerUnaryCall } from '@grpc/grpc-js';
interface HeroById {id: number;
}
interface Hero {id: number;name: string;
}
@Controller()
export class HeroesController {// 如下两个参数都是对应proto文件的内容,两个都可以省略,nestjs会自动转换名字大小写去匹配@GrpcMethod('HeroesService', 'FindOne')findOne(data: HeroById,metadata: Metadata,call: ServerUnaryCall<any, any>,): Hero {console.log('metadata', metadata);console.log('call', call);const items = [{ id: 1, name: 'John' },{ id: 2, name: 'Doe' },];return items.find(({ id }) => id === data.id);}
}
1.4 grpc客户端服务实现
说明:服务调用者可称为“服务消费者”或“服务客户端”
创建grpc服务客户端:nest generate app grpc-client
grpc-client.module.ts实现,注意在服务客户端也需要一份和提供者相同的proto文件,所以你需要把proto目录接拷贝到当前src目录下,我现在使用的是monorepo模式你也可以创建一个目录来存放所有proto文件。
import { Module } from '@nestjs/common';
import { GrpcClientController } from './grpc-client.controller';
import { GrpcClientService } from './grpc-client.service';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { join } from 'path';
@Module({imports: [ClientsModule.register([{name: 'HERO_SERVICE', //自定义服务名字transport: Transport.GRPC,options: {url: '127.0.0.1:3001', //调用的gRPC服务地址package: 'hero',protoPath: join(__dirname, '/proto/hero.proto'),},},]),],controllers: [GrpcClientController],providers: [GrpcClientService],
})
export class GrpcClientModule {}
grpc-client.controller.ts实现,这里是练习我就直接将代码写入controller中了,实际开发建议写入service中。不知道你是否还记得在前面提供者中也是用到了接口类型HeroById和Hero,在monorepo模式下你也可以对类型进行集中管理,把代码抽出去
import { Controller, Get, Inject, OnModuleInit } from '@nestjs/common';
import { GrpcClientService } from './grpc-client.service';
import { ClientGrpc } from '@nestjs/microservices';
import { Metadata } from '@grpc/grpc-js';
interface HeroById {id: number;
}
interface Hero {id: number;name: string;
}
interface HeroesService {findOne: (heroById: HeroById, metadata: Metadata) => Hero;
}
@Controller()
export class GrpcClientController implements OnModuleInit {private heroesService: HeroesService;constructor(private readonly grpcClientService: GrpcClientService,@Inject('HERO_SERVICE') private client: ClientGrpc,) {}onModuleInit() {this.heroesService = this.client.getService<HeroesService>('HeroesService');}@Get()getHero(): Hero {// 第二个参数可以传递元数据const metadata = new Metadata();metadata.add('Set-Cookie', 'yummy_cookie=choco');return this.heroesService.findOne({ id: 1 }, metadata);}
}
相关文章:
NestJS使用gRPC实现微服务通信
代码仓库地址:https://github.com/zeng-jc/rpc-grpc-practice 1.1 基本概念 gRPC 基于 Protocol Buffers(protobuf)作为接口定义语言(IDL),意味着你可以使用 protobuf 来定义你的服务接口,gRP…...
Android手机使用Termux终端模拟器
Termux 是 Android 平台上的一个终端模拟器,可以在 Android 手机上模拟 Linux 环境。它提供命令行界面,并且提供了功能健全的包管理工具(pkg)。另外就是 Termux 不需要 root 权限,安装后默认产生一个用户,可…...
【Linux】cp问题,生产者消费者问题代码实现
文章目录 前言一、 BlockQueue.hpp(阻塞队列)二、main.cpp 前言 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用…...
C++1114新标准——统一初始化(Uniform Initialization)、Initializer_list(初始化列表)、explicit
系列文章目录 C11&14新标准——Variadic templates(数量不定的模板参数) C11&14新标准——Uniform Initialization(统一初始化)、Initializer_list(初始化列表)、explicit 文章目录 系列文章目录1…...
Kubeadm 方式部署K8s集群
环境 主节点CPU核数必须是 ≥2核且内存要求必须≥2G,否则k8s无法启动 主机名地址角色配置kube-master192.168.134.165主节点2核4Gkube-node1192..168.134.166 工作节点2核4Gkube-node2192.168.134.163工作节点2核4G 1.获取镜像 谷歌镜像[由于国内网络原因…...
力扣376周赛
力扣第376场周赛 找出缺失和重复的数字 map模拟 class Solution { public:vector<int> findMissingAndRepeatedValues(vector<vector<int>>& grid) {int n grid.size() , m grid[0].size();map<int,int>mi;for(int i 0 ; i < n ; i ){for…...
SU渲染受到电脑性能影响大吗?如何提高渲染速度
一般3d设计师们在进行设计工作前都需要提供一台高配电脑,那么你这知道su渲染对电脑要求高吗?电脑带不动su怎么解决?su对电脑什么配件要求高?今天这篇文章就详细为大家带来电脑硬件对su建模渲染的影响,以及su渲染慢怎么…...
Docker - Android源码编译与烧写
创建源代码 并挂载到win目录 docker run -v /mnt/f/android8.0:/data/android8.0 -it --name android8.0 49a981f2b85f /bin/bash 使用 docker update 命令动态调整内存限制: 重新运行一个容器 docker run -m 512m my_container 修改运行中容器 显示运行中容器 d…...
股票价格预测 | Python实现基于ARIMA和LSTM的股票预测模型(含XGBoost特征重要性衡量)
文章目录 效果一览文章概述模型描述源码设计效果一览 文章概述 Python实现基于ARIMA和LSTM的股票预测模型(Stock-Prediction) Data ExtractionFormatting data for time seriesFeature engineering(Feature Importance using X...
Base64
1. Base64是什么? Base64(基底64)是一种基于64个可打印字符来表示二进制数据的表示方法。每6个比特为一个单元,对应某个可打印字符。3个字节相当于24个比特,对应于4个Base64单元,即3个字节可由4个可打印字…...
二叉搜索树的简单C++类实现
二叉搜索树(BST)是一种重要的数据结构,它对于理解树的操作和算法至关重要,其中序输出是有序的。本文通过C实现一个BST的类,并在插入和删除节点时提供清晰的输出,可视化这些操作的过程。 二叉搜索树的节点结…...
禁毒知识竞赛流程和规则
禁毒知识竞赛是一项全国性竞赛活动。有着深化全国青少年毒品预防教育,巩固学校毒品预防教育成果的重要作用。本文介绍一场禁毒知识竞赛的完整流程和规则,供单位组织此类活动时参考。 1、赛制 第一轮10进6,第二轮6进4,4支队伍决出…...
CSS 基础
文章目录 CSS 常见的属性CSS 常见样式行内样式内嵌样式导入样式 CSS 选择器标签选择器id选择器类选择器全局选择器属性选择器组合选择器 CSS 常见应用表格列表导航栏下拉菜单提示工具图片廊 CSS (Cascading Style Sheets,层叠样式表),是一种用…...
黑色翻页时钟HTML源码-倒计时单页翻页时钟
黑色翻页时钟HTML源码-倒计时单页翻页时钟这是一个类似fliqlo的黑色翻页时钟HTML源码,它仅包含一个HTML文件,上传到网站后即可使用。该时钟具有查看当前时间、秒表和倒计时功能,并且可以在页面的右下角进行设置。 红色动态炫酷数字时钟html网…...
2043杨辉三角(C语言)
目录 一:题目 二:思路分析 三:代码 一:题目 二:思路分析 1.通过杨辉三角,不难发现中间的数等于肩头两个数之和 2.但是当我们的输出结果,与杨辉三角的形式有所不同,但是我们可以找…...
【机器学习】从底层手写实现线性回归
【机器学习】Building-Linear-Regression-from-Scratch 线性回归 Linear Regression0. 数据的导入与相关预处理0.工具函数1. 批量梯度下降法 Batch Gradient Descent2. 小批量梯度下降法 Mini Batch Gradient Descent(在批量方面进行了改进)3. 自适应梯度…...
判断数组中对象的某个值是否有相同的并去重
如果你想判断数组中对象的某个值是否有相同的,并进行去重,你可以使用 JavaScript 中的一些数组方法和 Set 对象。以下是一个示例: // 原始数组包含对象 const array [{ id: 1, name: John },{ id: 2, name: Jane },{ id: 3, name: Doe },{ …...
Shell脚本 变量 语句 表达式
常见的解释器 #!/bin/sh #不推荐(了解) #!/bin/bash #!/usr/bin/python #!/bin/awk#!后跟的字符表示要启动的程序,该程序读取该文件执行。 #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行shell 函数 myShellName () {command1 }函数调用…...
MIT6.S081-实验准备
实验全程在Vmware虚拟机 (镜像:Ubuntu-20.04-beta-desktop-amd64) 中进行 一、版本控制 1.1 将mit的实验代码克隆到本地 git clone git://g.csail.mit.edu/xv6-labs-2020 1.2 修改本地git配置文件 创建github仓库,记录仓库地址 我的仓库地址就是htt…...
工具在手,创作无忧:一键下载安装Auto CAD工具,让艺术创作更加轻松愉悦!
不要再浪费时间在网上寻找Auto CAD的安装包了!因为你所需的一切都可以在这里找到!作为全球领先的设计和绘图软件,Auto CAD为艺术家、设计师和工程师们提供了无限的创作潜力。不论是建筑设计、工业设计还是室内装饰,Auto CAD都能助…...
Bootstrap-Sass 终极指南:如何在现代 Web 项目中快速集成 Bootstrap 3
Bootstrap-Sass 终极指南:如何在现代 Web 项目中快速集成 Bootstrap 3 【免费下载链接】bootstrap-sass Official Sass port of Bootstrap 2 and 3. 项目地址: https://gitcode.com/gh_mirrors/bo/bootstrap-sass Bootstrap-Sass 是 Bootstrap 3 的官方 Sass…...
终极React Native Navigation VR应用开发指南:打造沉浸式虚拟环境和菜单导航体验
终极React Native Navigation VR应用开发指南:打造沉浸式虚拟环境和菜单导航体验 【免费下载链接】react-native-navigation A complete native navigation solution for React Native 项目地址: https://gitcode.com/gh_mirrors/re/react-native-navigation …...
实测5款AI教材编写工具,低查重效果惊人,快速生成专业教材
许多教材编写者常常感到遗憾,他们费尽心思完善的正文内容,因为缺少配套资源而导致教学效果打折。设计课后练习题时,面对题型的多样化却缺乏创新的思路;制作可视化教学课件时,手头的技术能力又无法满足;深入…...
【模块化设计-14】深入解析 RT-Thread syswatch 系统监控模块:保障系统稳定的核心卫士
在嵌入式系统开发中,系统的稳定性是重中之重。RT-Thread 提供的 syswatch(系统监控)模块,专为解决线程异常阻塞、保障系统持续运行设计。本文将从模块设计理念、核心功能、配置项、工作流程到实际测试,全方位解析 sysw…...
零门槛云端实时物体识别:基于Google Colab与MobileNet V2的实践指南
1. 项目概述:零门槛体验云端实时物体识别想亲手体验一下人工智能的“眼睛”是如何看世界的吗?物体识别,这个听起来高深莫测的技术,其实离我们并不遥远。它就像是给计算机装上了一套视觉系统,让它能像我们一样ÿ…...
Claude与Figma智能协作:基于MCP协议的设计自动化实践
1. 项目概述:当Claude遇上Figma,设计协作的智能革命如果你是一名产品设计师或前端工程师,大概率经历过这样的场景:在Figma里反复调整一个组件的间距,只为找到那个“感觉对了”的数值;或者为了统一整个项目的…...
如何快速清理Windows驱动存储:Driver Store Explorer完整使用指南
如何快速清理Windows驱动存储:Driver Store Explorer完整使用指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer Driver Store Explorer(简称RAPR)是…...
避坑指南:用MOT17训练YOLOv7检测器时,为什么你的mAP上不去?可能是数据划分的锅
MOT17数据集划分陷阱:为什么你的YOLOv7检测器性能不达标? 当你在MOT17数据集上训练YOLOv7检测器时,是否遇到过这样的困境:损失曲线看起来完美,训练集准确率节节攀升,但验证集mAP却始终徘徊在低水平…...
基于RT-Thread与HMI-BOARD的直线推杆智能测试系统设计与实现
1. 项目概述与核心价值在工业自动化领域,直线推杆作为一种常见的执行机构,广泛应用于医疗床、升降桌、工业阀门、农业机械等设备中。一个推杆从设计图纸到批量生产,中间有一个至关重要的环节:寿命与可靠性测试。传统的测试方案&am…...
RT-Thread Studio实战:搞定DS18B20温度读取的时序坑(附逻辑分析仪调试实录)
RT-Thread Studio实战:DS18B20温度读取的时序调试与逻辑分析仪应用 嵌入式开发中,单总线器件因其简洁的硬件连接而广受欢迎,但恰恰是这种"简单"往往隐藏着最棘手的调试难题。当你在RT-Thread环境下使用DS18B20温度传感器࿰…...
