使用grpc开发RPC服务
grpc简介#
gRPC是谷歌开源的一款跨平台、高性能的RPC框架,目前主要使用它来进行后端微服务的开发。
可能会有的同学对RPC不太熟悉,其实在笔者看来,RPC和HTTP并无多大的区别都是一种调用方式,区别则是在于RPC会限制传输协议、传输的参数等,以此换取高效的传输流程,比如grpc就使用的是google开源的protobuf协议,使用TCP的方式进行传输,使得请求比起普通的JSON+HTPP更加快捷。关于更多protobuf的信息,可以查看这里
必要的准备#
- 了解Golang及其生态
- 安装gRPc及protobuf,教程
- 安装golang
- 安装protobuf编译器
一、首先我们需要定义好整个服务的protobuf文件user.proto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | syntax = "proto3"; // 指定语法格式,注意 proto3 不再支持 proto2 的 required 和 optional package proto; // 指定生成的 user.pb.go 的包名,防止命名冲突 // service 定义开放调用的服务,即 UserInfoService 微服务 service UserInfoService { // rpc 定义服务内的 GetUserInfo 远程调用 rpc GetUserInfo (UserRequest) returns (UserResponse) { } } // message 对应生成代码的 struct // 定义客户端请求的数据格式 message UserRequest { // [修饰符] 类型 字段名 = 标识符; string name = 1; } // 定义服务端响应的数据格式 message UserResponse { int32 id = 1; string name = 2; int32 age = 3; repeated string title = 4; // repeated 修饰符表示字段是可变数组,即 slice 类型 } |
然后我们通过protoc命令编译proto文件,生成对应的go文件
1 | protoc -I . --go_out=plugins=grpc:. ./user.proto |
二、我们来实现server.go
首先我们应该明确实现的步骤:
1、实现GetUserInfo接口
2、使用gRPC建立服务,监听端口
3、将我们实现的服务注册到gRPC中去
话不多说,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | package main import ( "fmt" "log" "net" // Import the generated protobuf code pb "go_mirco_service/proto" "golang.org/x/net/context" "google.golang.org/grpc" ) type UserInfoService struct{} var u = UserInfoService{} func (u *UserInfoService) GetUserInfo(ctx context.Context, req *pb.UserRequest) (resp *pb.UserResponse, err error) { name := req.Name if name == "leoython" { resp = &pb.UserResponse{ Id: 233, Name: name, Age: 20, Title: []string{"Gopher"}, } } err = nil return } func main() { port := ":2333" l, err := net.Listen("tcp", port) if err != nil { log.Fatalf("listen error: %v\n", err) } fmt.Printf("listen %s\n", port) s := grpc.NewServer() // 将 UserInfoService 注册到 gRPC // 注意第二个参数 UserInfoServiceServer 是接口类型的变量 // 需要取地址传参 pb.RegisterUserInfoServiceServer(s, &u) s.Serve(l) } |
到此我们就实现了利用gRPC实现了一个非常简单但是五脏俱全的RPC服务,但是却出现了一个问题,我们无法直接调用,所以我们还需要实现一个调用server的客户端,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | package main import ( "fmt" "log" pb "go_mirco_service/proto" "golang.org/x/net/context" "google.golang.org/grpc" ) func main() { conn, err := grpc.Dial(":2333", grpc.WithInsecure()) if err != nil { log.Fatalf("dial error: %v\n", err) } defer conn.Close() // 实例化 UserInfoService 微服务的客户端 client := pb.NewUserInfoServiceClient(conn) // 调用服务 req := new(pb.UserRequest) req.Name = "leoython" resp, err := client.GetUserInfo(context.Background(), req) if err != nil { log.Fatalf("resp error: %v\n", err) } fmt.Printf("Recevied: %v\n", resp) } |
结语#
至此,我们已经学会使用gRPC进行开发,采用protobuf进行参数的定义,下一篇笔者将会使用grpc-gateway将RPC接口转换为rest接口供客户端调用,而不需要客户端实现RPC,这也是现在主流微服务的一种服务提供方式,对外使用REST,对内使用RPC
可参考https://blog.csdn.net/Wendy_LWZ/article/details/81330799
thrift跨语言通信实例 https://blog.csdn.net/koli6678/article/details/80740749
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架