说到rpc就离不开多语言支持的grpc,我们来看一下Go语言下的grpc怎么用
建立rpc服务的基本流程 为了建立类似上图的基础rpc框架,我们有如下基本流程
定义gRPC服务。
生成客户端和服务器代码。
实现gRPC服务。
实现gRPC客户端。
这次我们的示例代码的目录结构如下
1. 定义rpc服务 首先进入目录helloworld编写proto文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 syntax = "proto3"; package helloworld; option go_package = "./"; // 定义打招呼服务 service SupGreeter { rpc SayHello (HelloRequest) returns (HelloReply){} } message HelloRequest { string name = 1; } message HelloReply{ string message = 1; }
2. 生成代码 然后我们生成Go语言代码,实现gRPC的客户端与服务端的接口
1 2 3 $ protoc -I. --go_out=plugins=grpc:. helloworld.proto $ ls helloworld.pb.go helloworld.proto
3. 实现rpc服务端服务 生成go.mod文件 我们进入根目录执行命令
服务端代码 我们进入./server来编写main.go文件
注意要导入接口模块
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 package mainimport ( "context" "log" "net" pb "grpcTest/helloworld" "google.golang.org/grpc" ) const ( port = ":50051" ) type server struct { pb.UnimplementedSupGreeterServer } func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error ) { log.Printf("Received: %v" , in.GetName()) return &pb.HelloReply{Message: "Sup say Hello to " + in.GetName()}, nil } func main () { lis, err := net.Listen("tcp" , port) if err != nil { log.Fatalf("fail to listen: %v" , err) } s := grpc.NewServer() pb.RegisterSupGreeterServer(s, &server{}) if err := s.Serve(lis); err != nil { log.Fatalf("fail to serve: %v" , err) } }
然后我们就可以go run main.go运行rpc服务端了,注意,要先启动服务端再启动客户端
4. 完成客户端代码 我们进入grpcTest/client
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 package mainimport ( "context" "log" "os" "time" pb "grpcTest/helloworld" "google.golang.org/grpc" ) const ( address = "localhost:50051" defaultName = "sup world" ) func main () { conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatalf("did not connect: %v" , err) } defer conn.Close() c := pb.NewSupGreeterClient(conn) name := defaultName if len (os.Args) > 1 { name = os.Args[1 ] } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("coudld not greet: %v" , err) } log.Printf("Greeting: %s" , r.Message) }
接下来我们就可以尝试运行几次客户端代码发起rpc调用了
客户端
1 2 3 4 supdriver@m700:~/Golang/grpcTest/client$ go run main.go 2025/11/11 06:43:04 Greeting: Sup say Hello to sup world supdriver@m700:~/Golang/grpcTest/client$ go run main.go 苦命鸳鸯 2025/11/11 06:43:18 Greeting: Sup say Hello to 苦命鸳鸯
服务端
1 2 3 supdriver@m700:~/Golang/grpcTest/server$ go run main.go 2025/11/11 06:43:04 Received: sup world 2025/11/11 06:43:18 Received: 苦命鸳鸯