gRPC for Go (Golang): 库和示例
什么是 gRPC,为什么在 Go 中需要它?
gRPC 是一个高性能的远程过程调用 (RPC) 框架,由 Google 开发。它使用 Protocol Buffers (protobuf) 进行数据序列化,并使用 HTTP/2 进行传输。在 Go 生态系统中,gRPC 已成为构建微服务架构的标准,因为它具有:
- 高性能(二进制协议、HTTP/2 多路复用)
- 强类型(生成的 Go 代码)
- 支持流式传输(客户端、服务器和双向)
- 内置身份验证和负载均衡
在本文中,我们将介绍主要的库、工具,并在 Golang 中编写一个完整的服务器和客户端示例。
必需的库和工具
在 Go 中使用 gRPC 需要:
google.golang.org/grpc— Go 的主要 gRPC 库google.golang.org/protobuf— 处理 Protocol Buffersprotoc— .proto 文件编译器protoc-gen-go— 从 .proto 生成 Go 代码的插件protoc-gen-go-grpc— 生成 gRPC 服务器/客户端代码的插件
安装工具
# 安装 protoc (Linux/macOS)sudo apt install protobuf-compiler # 或 brew install protobuf
# 安装 Go 插件go install google.golang.org/protobuf/cmd/protoc-gen-go@latestgo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# 检查protoc --versionprotoc-gen-go --version创建 .proto 文件
我们从在 hello.proto 文件中定义服务和消息开始:
syntax = "proto3";
package hello;
option go_package = "github.com/youruser/grpc-example/hello";
service Greeter { rpc SayHello (HelloRequest) returns (HelloReply); rpc SayHelloStream (HelloRequest) returns (stream HelloReply);}
message HelloRequest { string name = 1;}
message HelloReply { string message = 1;}生成 Go 代码
protoc --go_out=. --go-grpc_out=. hello.proto执行后,将出现两个文件:
hello.pb.go— 消息结构hello_grpc.pb.go— 服务器和客户端接口
在 Go 中实现 gRPC 服务器
创建文件 server.go:
package main
import ( "context" "log" "net"
"google.golang.org/grpc" pb "github.com/youruser/grpc-example/hello")
type server struct { pb.UnimplementedGreeterServer}
func (s *server) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) { log.Printf("Received: %v", req.GetName()) return &pb.HelloReply{Message: "Hello, " + req.GetName()}, nil}
func (s *server) SayHelloStream(req *pb.HelloRequest, stream pb.Greeter_SayHelloStreamServer) error { for i := 0; i < 5; i++ { if err := stream.Send(&pb.HelloReply{ Message: "Hello " + req.GetName() + " - " + fmt.Sprint(i), }); err != nil { return err } } return nil}
func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) }
s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{})
log.Println("Server listening on :50051") if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) }}在 Go 中实现 gRPC 客户端
创建文件 client.go:
package main
import ( "context" "log" "time"
"google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" pb "git