gRPC项目实战学习
这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
背景
目前在实习,对go web开发不太了解。正好借此次笔记活动记录自己学习的过程以及遇到的问题的解决办法。
环境安装
(我用的vscode,常用的还有Goland)
wsl安装
vscode安装
ubuntu安装
docker安装
go安装
mysql安装
redis安装
grpc库+protoc(2/3,看到抖音项目接口文档里用的是2)+protoc-gen-go+protobuf编译工具安装
(百度解决大部分问题,此处不记录安装过程的问题,已经忘了.jpg,或许有空会补链接)
upd:已经发布了安装过程教程地址
gRPC简单介绍
RPC的全称是Remote Procedure Call
,远程过程调用。这是一种协议,是用来屏蔽分布式计算中的各种调用细节,使得你可以像是本地调用一样直接调用一个远程的函数。
gRPC,用官方的话来说:
A high-performance, open-source universal RPC framework
。 gRPC是一个高性能的、开源的通用的RPC框架。 在gRPC中,我们称调用方为client,被调用方为server。
跟其他的RPC框架一样,gRPC也是基于”服务定义“的思想。简单的来讲,就是我们通过某种方式来描述一个服务,这种描述方式是语言无关的。在这个”服务定义“的过程中,我们描述了我们提供的服务服务名是什么,有哪些方法可以被调用,这些方法有什么样的入参,有什么样的回参。因此,gRPC
使用了Protocol Buffers
。
这是官方文档:Go | gRPC
gRPC的特性
- 使用Protocal Buffers——强大的结构数据序列化工具
- 可以跨语言使用
- 安装简单,扩展方便(用该框架每秒可达到百万个RPC)
- 基于HTTP2协议
gRPC使用流程
- 定义标准的proto文件
- 生成标准代码
- 服务端使用生成的代码提供服务
- 客户端使用生成的代码调用服务
笔记链接
-
proto2/3语言指南
-
gRPC快速入门
-
接口参考
过程
示例项目:使用 Protocol Buffers 作为前后端接口,开发一个简单的留言板message
。
项目结构
├── README.md
├── client
├── proto
└── server
定义标准的proto文件
在文件的第一行,我们写上:
syntax = "proto3";
说明我们使用的是proto3
语法。
然后写上:
option go_package = "生成文件包位置;message";
表示最后生成的go文件处于哪个包中,.
表示在当前目录生成。
定义message关键字,它的功能类似于Go中的结构体:
message Message {
string name = 1; //不是赋值,定义这个变量在Message中的位置
string title = 2;
}
定义一个服务,服务中需要有一个方法——接受客户端的参数,再返回服务端的相应。
service MessageService {
rpc SendMessage(SendMessageRequest) returns (SendMessageResponse) {}
}
我们的SendMessageRequest
和SendMessageResponse
可以定义成以下这样:
message SendMessageRequest {
string name = 1;
}
message SendMessageResponse {
string responseName = 1;
}
生成标准代码
在proto文件中写完这些后,在proto文件目录下执行以下命令:
protoc --go_out=. message.proto
protoc --go-grpc_out=. message.proto
可以看到当前的目录生成了message.pb.go
和message_grpc.pb.go
。
可能需要注意的问题:
- 更新版本的
protoc-gen-go
,但是用了旧版本的生成命令。 - google/github版本的生成命令和生成文件不同。
- 安装protoc时遇到的小坑,运行报错:
google/protobuf/xxxx.proto: File not found.
message/message.proto:5:1: Import “google/protobuf/xxxx.proto” was not found or had errors
message/message.proto:21:5: “google.protobuf.xxxx is not defined.
原因:文件夹里有readme.txt, 没仔细阅读。
解决:需要尝试着把 include/google
移动到 本机的 /usr/local/include/google
重新生成。
- 找不到我们要import的proto文件
Import "google/api/annotations.proto" was not found or had errors.
尝试下载mod,但无法指定依赖,暂未找到原因。
歪解:把引用该包的句子删了。
更详细的资料:Release v1.20.0 · protocolbuffers/protobuf-go (github.com)
服务端
注册
在server目录下创建server.go
,加入以下代码:
type server struct {
Send func(context.Context, *SendMessageRequest) (*SendMessageResponse, error)
}
func CreateGrpcServer() *grpc.Server {
s := grpc.NewServer()
pb.RegisterMessageServiceServer(s, &server{})
return s
}
这部分我们创建了一个GrpcServer
,注册了Service
。在server
实例中有一个方法,这个方法就是我们定义的Send方法,我们需要在服务端实现这个方法:
func SendMessage(ctx context.Context, req *SendMessageRequest) (*Message, error) {
log.Println("receive message:", req.Get())
resp := &SendMessageResponse{}
resp.Response = "!"
return nil, status.Errorf(codes.Unimplemented, "method GetMessage not implemented")
}
那么已成功在服务端实现我们声明的方法。
监听
类似于web服务器,先创建Handler再对端口进行监听。
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := impl.CreateGrpcServer()
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
监听port
端口的TCP连接,然后启动服务器。
那么服务端的开发已经完毕~
客户端
在客户端中,我们应该先与服务端建立连接,然后才能够调用各种方法。先跟port
端口建立连接。
conn, err := grpc.Dial(port, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
按照定义,我们调用服务端的方法。
client := message.NewMessageServiceClient(conn)
resp, err := client.Send(context.Background(), &SendMessageRequest{})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
即在本地创建一个client,然后调用早就定义好的Send方法,就可以将服务端和客户端都运行起来。
至此message的开发完毕~
整理一下:
我们在.proto
文件中定义方法,在服务端实现定义的RPC方法的具体逻辑,然后在客户端调用方法。
其他的部分,由proto buffer
负责对Golang
中存储的数据结构与RPC
传输中的数据进行转换,gRPC
负责封装所有的逻辑。
写在最后
- 这些代码可以进一步完善,此处只做了简要的记录和说明,如有错误/修改意见请读者联系我~
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战