gRPC框架

1、gRPC 与 Protobuf 介绍

  • 微服务架构中,由于每个服务对应的代码库是独立运行的,无法直接调用,彼此间
    的通信就是个大问题
  • gRPC 可以实现微服务, 将大的项目拆分为多个小且独立的业务模块, 也就是服务,
    各服务间使用高效的protobuf 协议进行RPC 调用, gRPC 默认使用protocol buffers,
    这是 google 开源的一套成熟的结构数据序列化机制(当然也可以使用其他数据格
    式如JSON)
  • 可以用 proto files 创建 gRPC 服务,用 message 类型来定义方法参数和返回类型

参考文章:gRPC教程

2、Mac下安装Protobuf和gRPC

参考文章:https://cloud.tencent.com/developer/article/2163004

brew命令安装

1. 安装的是 gRPC 的核心库
brew install grpc2. 安装的是protocol编译器
brew install protobuf3. 各个语言的代码生成工具,对于 Golang 来说,称为 protoc-gen-go
brew install protoc-gen-go
brew install protoc-gen-go-grpc

查看安装是否成功

apple@appledeMacBook-Pro ~ % protoc --version
libprotoc 25.1
apple@appledeMacBook-Pro ~ % protoc-gen-go --version
protoc-gen-go v1.31.0
apple@appledeMacBook-Pro ~ % protoc-gen-go-grpc --version
protoc-gen-go-grpc 1.3.0

如果查不到指令,检查一下环境变量

export GOPATH="/Users/apple/go"
export PATH=$PATH:$GOPATH/bin

3、Demo1

3.1 目录结构

实现服务端和客户端的数据传输

├── client
│   └── client.go
├── go.mod
├── go.sum
├── proto
│   └──  user.proto
└── server└── server.go

3.2 user.proto编写

// 编译指令:protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/user.proto// 版本号
syntax = "proto3";// 生成文件所在的目录
option go_package="/proto";// 制定生成 user.pb.go 的包名
package proto;// 定义message服务端响应的数据格式,相当于结构体,
message UserInfoResponse {// 定义字段,相当于结构体的属性int32 id = 1;string name = 2;int32 age = 3;// 字段修饰符,repeated表示可以重复出现,就是可变数组,类似于切片类型repeated string hobbies = 4;
}// 定义message客户端请求的数据格式,相当于结构体,
message UserInfoRequest {// 定义字段,相当于结构体的属性string name = 1;
}// 定义一个service服务,相当于接口
service UserInfoService {// 定义一个rpc方法,相当于接口方法// 定义请求参数为UserInfoRequest,返回值为UserInfoResponserpc GetUserInfo(UserInfoRequest) returns (UserInfoResponse);
}

执行编译指令

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/user.proto

这是一个使用 Protocol Buffers(protobuf)和 Go gRPC 插件生成代码的示例命令。该命令根据 proto/user.proto 文件生成对应的 Go 代码。

这个命令的参数含义如下:

--go_out=.:指定生成的 Go 代码输出目录为当前目录。
--go_opt=paths=source_relative:设置生成的 Go 代码中的导入路径为相对于源文件的相对路径。
--go-grpc_out=.:指定生成的 Go gRPC 代码输出目录为当前目录。
--go-grpc_opt=paths=source_relative:设置生成的 Go gRPC 代码中的导入路径为相对于源文件的相对路径。
proto/user.proto:指定要生成代码的 protobuf 文件路径。

最后会在proto目录下生成user.pb.go和user_grpc.pb.go

  • user.pb.go:这个文件包含了用户自定义的消息类型的定义,它描述了在通信过程中需要传输的数据结构,比如用户信息、请求参数等。
  • user_grpc.pb.go:这个文件包含了用户自定义的服务接口的定义,它描述了可以远程调用的方法和参数,以及返回值等。

3.3 server服务端

package mainimport ("context""fmt"pb "main/proto""net""google.golang.org/grpc"
)// 定义服务端实现约定的接口
type UserInfoService struct {pb.UnimplementedUserInfoServiceServer
}// 实现服务端需要实现的接口
func (s *UserInfoService) GetUserInfo(ctx context.Context, req *pb.UserInfoRequest) (resp *pb.UserInfoResponse, err error) {// 服务端接收参数name,再进行业务操作name := req.Nameif name == "zs" {resp = &pb.UserInfoResponse{Id:      1,Name:    name,Age:     18,Hobbies: []string{"swimming", "running"},}}err = nilreturn
}func main() {// 1. 监听addr := "127.0.0.1:8080"lis, err := net.Listen("tcp", addr)if err != nil {fmt.Println("监听异常, err = ", err)return}fmt.Println("开始监听:", addr)// 2. 实例化gRPCs := grpc.NewServer()// 3. 在gRPC上注册微服务,第二个参数要接口类型的变量pb.RegisterUserInfoServiceServer(s, &UserInfoService{})// 4. 启动gRPC服务端s.Serve(lis)
}

3.4 client客户端

package mainimport ("context""fmt"pb "main/proto""google.golang.org/grpc"//"google.golang.org/grpc/credentials/insecure"
)func main() {// 1. 创建与gRPC服务器的连接addr := "127.0.0.1:8080"conn, err := grpc.Dial(addr, grpc.WithInsecure())if err != nil {fmt.Println("连接异常, err = ", err)return}defer conn.Close()// 2. 实例化gRPC客户端client := pb.NewUserInfoServiceClient(conn)// 3. 组装参数req := new(pb.UserInfoRequest)req.Name = "zs"// 4. 调用接口resp, err := client.GetUserInfo(context.Background(), req)if err != nil {fmt.Println("响应异常, err = ", err)return}fmt.Println("响应结果, resp = ", resp)
}

3.5 编译

先执行服务端,再执行客户端
在这里插入图片描述

4、Demo2

4.1 目录结构

├── client
│   └── client.go
├── go.mod
├── go.sum
├── proto
│   └── hello.proto
└── server└── server.go

4.2 hello.proto

// 编译指令:protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/hello.protosyntax = "proto3";option go_package="/proto";package Business;service Hello {rpc Say (SayRequest) returns (SayResponse);
}message SayResponse {string Message = 1;
}message SayRequest {string Name = 1;
}

4.3 server服务端

package mainimport ("context""fmt""google.golang.org/grpc""main/proto""net"
)type server struct {proto.UnimplementedHelloServer
}func (s *server) Say(ctx context.Context, req *proto.SayRequest) (*proto.SayResponse, error) {fmt.Println("request:", req.Name)return &proto.SayResponse{Message: "Hello " + req.Name}, nil
}func main() {listen, err := net.Listen("tcp", ":8001")if err != nil {fmt.Printf("failed to listen: %v", err)return}s := grpc.NewServer()proto.RegisterHelloServer(s, &server{})//reflection.Register(s)defer func() {s.Stop()listen.Close()}()fmt.Println("Serving 8001...")err = s.Serve(listen)if err != nil {fmt.Printf("failed to serve: %v", err)return}
}

4.4 client客户端

package mainimport ("bufio""context""fmt""main/proto""os""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"
)func main() {var serviceHost = "127.0.0.1:8001"conn, err := grpc.Dial(serviceHost, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {fmt.Println(err)}defer conn.Close()client := proto.NewHelloClient(conn)rsp, err := client.Say(context.TODO(), &proto.SayRequest{Name: "BOSIMA",})if err != nil {fmt.Println(err)}fmt.Println(rsp)fmt.Println("按回车键退出程序...")in := bufio.NewReader(os.Stdin)_, _, _ = in.ReadLine()
}

4.5 编译

在这里插入图片描述

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

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

相关文章

如何做一名“机关算尽”的伦敦银投资者?

做伦敦银投资者有一个好处,就是这个世界上投资者均可以参与的市场会比较公平,所以我们从书中、从课程中学习到的分析方法,可以应用在该市场中。其中有一种方法,可以通过计算,算出银价转折、反转的点位等等。那我们如何…

拆解大语言模型 RLHF 中的PPO算法

为什么大多数介绍大语言模型 RLHF 的文章,一讲到 PPO 算法的细节就戛然而止了呢?要么直接略过,要么就只扔出一个 PPO 的链接。然而 LLM x PPO 跟传统的 PPO 还是有些不同的呀。 其实在 ChatGPT 推出后的相当一段时间内,我一直在等…

一些AG10K FPGA 调试的建议-Douglas

PLL AGM FPGA 在配置成功时,PLL 已经完成锁定,lock 信号已经变高;如果原设计中用 lock 信号输出实现系统 reset 的复位功能,就不能正确完成上电复位;同时,为了保证 PLL 相移的稳定,我们需要在 P…

RabbitMq的详细使用

消息队列RabbitMQ详细使用 文章目录 消息队列RabbitMQ详细使用MQ 的相关概念什么是MQ为什么要用MQMQ 的分类MQ 的选择 RabbitMQRabbitMQ 的概念四大核心概念各个名词介绍安装RabbitMQWeb管理界面及授权操作Docker 安装Hello world简单示例 Work Queues轮训分发消息消息应答自动…

Java编程中通用的正则表达式(一)

正则表达式(Regular Expression,简称RegEx),又称常规表示法、正则表示、正规表示式、规则表达式、常式、表达式等,是计算机科学中的一个概念。正则表达式是用于描述某种特定模式的字符序列,特别是用来匹配、…

设计模式(二)-创建者模式(5)-建造者模式

一、为何需要建造者模式(Builder)? 在软件系统中,会存在一个复杂的对象,复杂在于该对象包含了很多不同的功能模块。该对象里的各个部分都是按照一定的算法组合起来的。 为了要使得复杂对象里的各个部分的独立性,以及…

大模型学习之GPT系列

GPT系列 预备知识GPT-1无监督预训练有监督的微调训练 GPT-2数据集:输入表示模型实验 GPT-3模型数据集实验局限性 InstructGPTGPT-4GPT-4 新特性基础能力 参考文献 大模型 GPT演进路线图 预备知识 Transformer 结构图 GPT-1 首先使用未标注的数据训练一个预训练…

速学数据结构 | 树 森林 二叉树 的概念详讲篇

🎬 鸽芷咕:个人主页 🔥 个人专栏:《速学数据结构》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活! 📋 前言 🌈hello! 各位宝子们大家好啊,关于线性表我们已经在前面更新完了…

c YUV 转 JPEG(准备霍夫曼编码)

先取yuv 文件中一个168的块,跑通全流程 理解与思路: 1.块分割 YUV 文件分为:YUV444 YUV 422 YUV420。444:就是:12个char 有4个Y,4个U,4个 U,422:8个char 中有4个Y &#x…

西科大微机原理实验四(定时器程序设计)

任务一、 按实验要求内容新建一个ASM41.ASM文件,使用masm命令生成obj文件并输入 上述源程序中使用了外部资源,该外部资源存在于文件 LIB_TIM.OBJ中,因此使用link命令将 ASM41.OBJ 和 LIB_TIM.OBJ 一起链接生成可执行文件 使用debug加载程序并进行调试 使用-g指令,回显如下…

技术分享 | 想做App测试就一定要了解的App结构

app 的结构包含了 APK 结构和 app 页面结构两个部分 APK结构 APK 是 Android Package 的缩写,其实就是 Android 的安装包。通过将 APK 文件直接传到 Android 模拟器或 Android 手机中执行即可安装。 APK 文件其实是 zip 格式,但后缀名被修改为 apk&…

Mysql进阶-InnoDB引擎事务原理及MVCC

事务原理 事务基础 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。 事务的四大特性: 原子性(A…

抖去推--短视频剪辑、矩阵无人直播saas营销工具一站式开发

抖去推是一款短视频剪辑和矩阵无人直播SAAS营销工具一站式开发平台。它提供了以下功能和特点: 1. 短视频剪辑:抖去推提供了一系列的剪辑工具,包括自动剪辑、特效制作、配音配乐等,可以帮助用户轻松制作出高质量的短视频。 2. 矩阵…

Java实现一个简单的贪吃蛇小游戏

一. 准备工作 首先获取贪吃蛇小游戏所需要的头部、身体、食物以及贪吃蛇标题等图片。 然后,创建贪吃蛇游戏的Java项目命名为snake_game,并在这个项目里创建一个文件夹命名为images,将图片素材导入文件夹。 再在src文件下创建两个包&#xff0…

阿里云SLB的使用总结

一、什么是SLB 实现k8s的服务service的一种推荐方式,也是服务上云后,替代LVS的一个必选产品。 那么它有什么作用呢? 1、负载均衡,是它与生俱来的。可以配置多个服务器组:包括虚拟服务器组、默认服务器组、主备服务器…

鸿蒙原生应用/元服务开发-Stage模型能力接口(二)

ohos.app.ability.AbilityConstant (AbilityConstant)一、说明 AbilityConstant提供Ability相关的枚举,包括设置初次启动原因、上次退出原因、迁移结果、窗口类型等。本模块首批接口从API version 9开始支持。后续版本的新增接口,采用上角标单独标记接口…

python读取csv文件

在Python中,你可以使用pandas库来读取CSV文件。以下是一个基本的例子: import pandas as pd# 读取CSV文件data pd.read_csv(filename.csv)# 显示前几行数据print(data.head()) 这里,filename.csv应该被替换为你的CSV文件的实际路径和名称。…

多合一iPhone 解锁工具:iMyFone LockWiper iOS

多合一iPhone 解锁工具 无需密码解锁 iPhone/iPad/iPod touch 上所有类型的屏幕锁定 在几分钟内解锁 iPhone Apple ID、Touch ID 和 Face ID 立即绕过 MDM 并删除 iPhone/iPad/iPod touch 上的 MDM 配置文件 支持所有 iOS 版本和设备,包括最新的 iOS 17 和 iPhone 1…

学生管理系统 数据库版

1.写SQL语句 创建school_java数据库 创建student数据表包含 id、name姓名、tel电话、sex性别字段 往student表中加10条数据 2.写Java代码(要求只用PreparedStatement对象,变化的值都用?代替) 查询student表中所有学生信息 student表中新增三…

2023年国赛高教杯数学建模A题定日镜场的优化设计解题全过程文档及程序

2023年国赛高教杯数学建模 A题 定日镜场的优化设计 原题再现 构建以新能源为主体的新型电力系统,是我国实现“碳达峰”“碳中和”目标的一项重要措施。塔式太阳能光热发电是一种低碳环保的新型清洁能源技术[1]。   定日镜是塔式太阳能光热发电站(以下…