当前位置: 首页 > news >正文

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.tsheroes.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实现微服务通信

代码仓库地址&#xff1a;https://github.com/zeng-jc/rpc-grpc-practice 1.1 基本概念 gRPC 基于 Protocol Buffers&#xff08;protobuf&#xff09;作为接口定义语言&#xff08;IDL&#xff09;&#xff0c;意味着你可以使用 protobuf 来定义你的服务接口&#xff0c;gRP…...

Android手机使用Termux终端模拟器

Termux 是 Android 平台上的一个终端模拟器&#xff0c;可以在 Android 手机上模拟 Linux 环境。它提供命令行界面&#xff0c;并且提供了功能健全的包管理工具&#xff08;pkg&#xff09;。另外就是 Termux 不需要 root 权限&#xff0c;安装后默认产生一个用户&#xff0c;可…...

【Linux】cp问题,生产者消费者问题代码实现

文章目录 前言一、 BlockQueue.hpp&#xff08;阻塞队列&#xff09;二、main.cpp 前言 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯&#xff0c;而通过阻塞队列来进行通讯&#xff0c;所以生产者生产完数据之后不用…...

C++1114新标准——统一初始化(Uniform Initialization)、Initializer_list(初始化列表)、explicit

系列文章目录 C11&14新标准——Variadic templates&#xff08;数量不定的模板参数&#xff09; C11&14新标准——Uniform Initialization&#xff08;统一初始化&#xff09;、Initializer_list&#xff08;初始化列表&#xff09;、explicit 文章目录 系列文章目录1…...

Kubeadm 方式部署K8s集群

环境 主节点CPU核数必须是 ≥2核且内存要求必须≥2G&#xff0c;否则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设计师们在进行设计工作前都需要提供一台高配电脑&#xff0c;那么你这知道su渲染对电脑要求高吗&#xff1f;电脑带不动su怎么解决&#xff1f;su对电脑什么配件要求高&#xff1f;今天这篇文章就详细为大家带来电脑硬件对su建模渲染的影响&#xff0c;以及su渲染慢怎么…...

Docker - Android源码编译与烧写

创建源代码 并挂载到win目录 docker run -v /mnt/f/android8.0:/data/android8.0 -it --name android8.0 49a981f2b85f /bin/bash 使用 docker update 命令动态调整内存限制&#xff1a; 重新运行一个容器 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是什么&#xff1f; Base64&#xff08;基底64&#xff09;是一种基于64个可打印字符来表示二进制数据的表示方法。每6个比特为一个单元&#xff0c;对应某个可打印字符。3个字节相当于24个比特&#xff0c;对应于4个Base64单元&#xff0c;即3个字节可由4个可打印字…...

二叉搜索树的简单C++类实现

二叉搜索树&#xff08;BST&#xff09;是一种重要的数据结构&#xff0c;它对于理解树的操作和算法至关重要&#xff0c;其中序输出是有序的。本文通过C实现一个BST的类&#xff0c;并在插入和删除节点时提供清晰的输出&#xff0c;可视化这些操作的过程。 二叉搜索树的节点结…...

禁毒知识竞赛流程和规则

禁毒知识竞赛是一项全国性竞赛活动。有着深化全国青少年毒品预防教育&#xff0c;巩固学校毒品预防教育成果的重要作用。本文介绍一场禁毒知识竞赛的完整流程和规则&#xff0c;供单位组织此类活动时参考。 1、赛制 第一轮10进6&#xff0c;第二轮6进4&#xff0c;4支队伍决出…...

CSS 基础

文章目录 CSS 常见的属性CSS 常见样式行内样式内嵌样式导入样式 CSS 选择器标签选择器id选择器类选择器全局选择器属性选择器组合选择器 CSS 常见应用表格列表导航栏下拉菜单提示工具图片廊 CSS (Cascading Style Sheets&#xff0c;层叠样式表&#xff09;&#xff0c;是一种用…...

黑色翻页时钟HTML源码-倒计时单页翻页时钟

黑色翻页时钟HTML源码-倒计时单页翻页时钟这是一个类似fliqlo的黑色翻页时钟HTML源码&#xff0c;它仅包含一个HTML文件&#xff0c;上传到网站后即可使用。该时钟具有查看当前时间、秒表和倒计时功能&#xff0c;并且可以在页面的右下角进行设置。 红色动态炫酷数字时钟html网…...

2043杨辉三角(C语言)

目录 一&#xff1a;题目 二&#xff1a;思路分析 三&#xff1a;代码 一&#xff1a;题目 二&#xff1a;思路分析 1.通过杨辉三角&#xff0c;不难发现中间的数等于肩头两个数之和 2.但是当我们的输出结果&#xff0c;与杨辉三角的形式有所不同&#xff0c;但是我们可以找…...

【机器学习】从底层手写实现线性回归

【机器学习】Building-Linear-Regression-from-Scratch 线性回归 Linear Regression0. 数据的导入与相关预处理0.工具函数1. 批量梯度下降法 Batch Gradient Descent2. 小批量梯度下降法 Mini Batch Gradient Descent&#xff08;在批量方面进行了改进&#xff09;3. 自适应梯度…...

判断数组中对象的某个值是否有相同的并去重

如果你想判断数组中对象的某个值是否有相同的&#xff0c;并进行去重&#xff0c;你可以使用 JavaScript 中的一些数组方法和 Set 对象。以下是一个示例&#xff1a; // 原始数组包含对象 const array [{ id: 1, name: John },{ id: 2, name: Jane },{ id: 3, name: Doe },{ …...

Shell脚本 变量 语句 表达式

常见的解释器 #!/bin/sh #不推荐(了解) #!/bin/bash #!/usr/bin/python #!/bin/awk#!后跟的字符表示要启动的程序&#xff0c;该程序读取该文件执行。 #! 是一个约定的标记&#xff0c;它告诉系统这个脚本需要什么解释器来执行shell 函数 myShellName () {command1 }函数调用…...

MIT6.S081-实验准备

实验全程在Vmware虚拟机 (镜像&#xff1a;Ubuntu-20.04-beta-desktop-amd64) 中进行 一、版本控制 1.1 将mit的实验代码克隆到本地 git clone git://g.csail.mit.edu/xv6-labs-2020 1.2 修改本地git配置文件 创建github仓库&#xff0c;记录仓库地址 我的仓库地址就是htt…...

工具在手,创作无忧:一键下载安装Auto CAD工具,让艺术创作更加轻松愉悦!

不要再浪费时间在网上寻找Auto CAD的安装包了&#xff01;因为你所需的一切都可以在这里找到&#xff01;作为全球领先的设计和绘图软件&#xff0c;Auto CAD为艺术家、设计师和工程师们提供了无限的创作潜力。不论是建筑设计、工业设计还是室内装饰&#xff0c;Auto CAD都能助…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...