说到rpc就离不开多语言支持的grpc,我们来看一下Go语言下的grpc怎么用

建立rpc服务的基本流程


为了建立类似上图的基础rpc框架,我们有如下基本流程

  1. 定义gRPC服务。
  2. 生成客户端和服务器代码。
  3. 实现gRPC服务。
  4. 实现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 # 执行之后我我们查看生成的 .pb.go文件
helloworld.pb.go helloworld.proto

3. 实现rpc服务端服务

生成go.mod文件

我们进入根目录执行命令

1
go mod init grpcTest

服务端代码

我们进入./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 main

import (
"context"
"log"
"net"

pb "grpcTest/helloworld"

"google.golang.org/grpc"
)

const (
port = ":50051"
)

// 封装rpc服务对象
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()
// 注册rpc服务
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 main

import (
"context"
"log"
"os"
"time"

pb "grpcTest/helloworld"

"google.golang.org/grpc"
)

const (
address = "localhost:50051"
defaultName = "sup world"
)

func main() {
// 建立网络连接,创建grpc会话
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
// 创建grpc客户端对象
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()
// rpc调用
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: 苦命鸳鸯