go语言gRPC系列(一) - gRPC入门

1. 前言#

之前学习的go的微服务之间还是通过REST API的方式互相调用的,但既然要学习微服务,gRPC肯定是一个绕不过去的需要学习的技术, 所以就开搞吧

2. gRPC与Protobuf简介#

gRPC是一款语言中立平台中立、开源的远程过程调用系统

即:gRPC客户端和服务端可以在多种环境中运行和交互,例如用java写一个服务端,可以用go语言写客户端调用

微服务架构中,由于每个服务对应的代码库是独立运行的,无法直接调用,彼此间的通信就是个大问题.

gRPC可以实现将大的项目拆分为多个小且独立的业务模块,也就是服务。各服务间使用高效的protobuf协议进行RPC调用,gRPC默认使用protocol buffers,这是google开源的一套成熟的结构数据序列化机制

当然也可以使用其他数据格式如JSON

可以用proto files创建gRPC服务,用message类型来定义方法参数和返回类型

3. 安装#

  • 第一步:下载grpc通用编译器

如下图,解压出来因平台而异会是一个protoc或者protoc.exe

https://github.com/protocolbuffers/protobuf/releases

  • 第二步:把下载的二进制文件路径添加到环境变量中(为了能全局访问protoc)
    • 这里以为mac为例子
Copy
# 打开存放环境变量的文件 vim ~/.bash_profile # 添加如下,后面是路径 alias protoc="/Users/emm/others/protoc-3.12.4-osx-x86_64/bin/protoc" # 刷新环境变量 source ./.bash_profile
  • 第三步: 安装go专用的protoc的生成器

go get github.com/golang/protobuf/protoc-gen-go

安装后会在GOPATH目录下生成可执行文件,protobuf的编译器插件protoc-gen-go,等下执行protoc命令会自动调用这个插件

4. 中间文件演示#

4.1 编写中间文件#

这里新建一个pbfiles文件夹用于存放protoc文件

Copy
// 这个就是protobuf的中间文件 // 指定的当前proto语法的版本,有2和3 syntax = "proto3"; // 指定等会文件生成出来的package package service; // 定义request message ProductRequest{ int32 prod_id = 1; // 1代表顺序 } // 定义response message ProductResponse{ int32 prod_stock = 1; // 1代表顺序 }

4.2 运行protoc命令编译成go中间文件#

然后运行以下的命令来生成.go结尾的文件

  • 下面的命令就是我们刚刚下的protoc包以及protoc-gen-go插件的作用
Copy
# 编译Product.proto之后输出到service文件夹 protoc --go_out=../service Product.proto

如下就在service文件夹自动生成了一个go文件,并且它提示我们不要去修改它

5. 创建gRPC服务端#

5.1 新建Product.protoc#

这个protoc文件比上面的多出了一个service的定义和里面的一个方法的定义

Copy
// 这个就是protobuf的中间文件 // 指定的当前proto语法的版本,有2和3 syntax = "proto3"; // 指定等会文件生成出来的package package service; // 定义request model message ProductRequest{ int32 prod_id = 1; // 1代表顺序 } // 定义response model message ProductResponse{ int32 prod_stock = 1; // 1代表顺序 } // 定义服务主体 service ProdService{ // 定义方法 rpc GetProductStock(ProductRequest) returns(ProductResponse); }

5.2 运行protoc命令#

注意

  • 这里的protoc命令和之前的命令相比有点不一样
Copy
protoc --go_out=plugins=grpc:../service Product.proto

然后还是会在service文件夹下生成一个.go的文件

有两个比较需要注意的

  1. RegisterProdServiceServer

后面需要在server中调用这个来注册

  1. ProdServiceServer的接口定义

我们需要继承这个接口,即实现它所有的方法

5.3 实现RegisterProdServiceServer接口#

上面我们在protoc文件中定义了一个ProdService中包含了一个GetProductStock的方法

这里我们要实现自动生成的go文件中的接口

Copy
package service import "context" type ProdService struct { } func (ps *ProdService) GetProductStock(ctx context.Context, request *ProductRequest) (*ProductResponse, error) { return &ProductResponse{ProdStock: request.ProdId}, nil }

5.4 准备工作完成,创建main函数将服务端跑起来#

前面的都是准备工作,这里是真正把服务端跑起来的操作

下面是服务端代码:

Copy
package main import ( "gomicro-quickstart/grpc_demo/service" "google.golang.org/grpc" "log" "net" ) func main() { // 1. new一个grpc的server rpcServer := grpc.NewServer() // 2. 将刚刚我们新建的ProdService注册进去 service.RegisterProdServiceServer(rpcServer, new(service.ProdService)) // 3. 新建一个listener,以tcp方式监听8082端口 listener, err := net.Listen("tcp", ":8082") if err != nil { log.Fatal("服务监听端口失败", err) } // 4. 运行rpcServer,传入listener _ = rpcServer.Serve(listener) }

排坑

  • 如果遇见类似undefined: grpc.SupportPackageIsVersion6undefined: grpc.ClientConnInterface的错误,可以修改go.mod将grpc版本改到1.27.0


6. 创建gRPC客户端#

  • 新建一个grpc_client文件夹存放客户端相关的
  • 并在grpc_client文件夹下再新建一个service文件夹

6.1 拷贝Product.pb.go到客户端service文件夹下#

6.2 编写client的main函数#

Copy
package main import ( "context" "fmt" "gomicro-quickstart/grpc_client/service" "google.golang.org/grpc" "log" ) func main() { // 1. 新建连接,端口是服务端开放的8082端口 // 并且添加grpc.WithInsecure(),不然没有证书会报错 conn, err := grpc.Dial(":8082", grpc.WithInsecure()) if err != nil { log.Fatal(err) } // 退出时关闭链接 defer conn.Close() // 2. 调用Product.pb.go中的NewProdServiceClient方法 productServiceClient := service.NewProdServiceClient(conn) // 3. 直接像调用本地方法一样调用GetProductStock方法 resp, err := productServiceClient.GetProductStock(context.Background(), &service.ProductRequest{ProdId: 233}) if err != nil { log.Fatal("调用gRPC方法错误: ", err) } fmt.Println("调用gRPC方法成功,ProdStock = ", resp.ProdStock) }

6.3 运行并显示结果#

  • 先把服务端运行起来
  • 再把客户端运行起来

然后客户端输出正确的结果,第一个go的gRPC调用运行成功

posted @   宝树呐  阅读(14359)  评论(3编辑  收藏  举报
编辑推荐:
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示
CONTENTS