grpc的使用

安装

先安装protobuf的C库

然后安装protoc工具

1
2
3
go get -u github.com/golang/protobuf/proto

go get -u github.com/golang/protobuf/protoc-gen-go

最后安装gRPC-go

1
go get google.golang.org/grpc

使用

首先写一个proto协议文件test.proto

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
syntax = "proto3";

package test;

service Test {
rpc Ping(TestRequest) returns (TestResponse) {}
}

message TestRequest {
string name = 1;
}

message TestResponse {
string message = 1;
}

这里的name = 1,代表着协议中字段的顺序,当扩展字段后,该值不能变,否则会导致协议不一致

生成代码

1
protoc --go_out=plugins=grpc:. test.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
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
73
74
75
76
77
78
79
80
81
package main

import (
"google.golang.org/grpc"
test "./test"
"net"
"golang.org/x/net/context"
)

type server struct{}

func (s *server) Ping(ctx context.Context, in *test.TestRequest) (*test.TestResponse, error) {
return &test.TestResponse{Message: "Hello " + in.Name}, nil
}

func main() {
lis, err := net.Listen("tcp","127.0.0.1:50051")
if err != nil {
return
}
s := grpc.NewServer()
test.RegisterTestServer(s, &server{})
s.Serve(lis)
}
```

编写客户端性能测试代码

```c
package main

import (
"google.golang.org/grpc"
test "./test"
"golang.org/x/net/context"
"fmt"
"time"
)

var count, lastcount int64

func main() {
conn,err := grpc.Dial("127.0.0.1:50051",grpc.WithInsecure())
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
c := test.NewTestClient(conn)
for i := 0;i != 100;i++ {
go func() {
for ;; {
_, err := c.Ping(context.Background(), &test.TestRequest{Name: "cy"})
if err != nil {
fmt.Println(err)
return
}
count++
}
}()
}
for ;; {
lastcount = count
time.Sleep(time.Second)
fmt.Println(count - lastcount)
}
}
```

## 扩展

这只是最简单的应用

实际的使用是需要扩展的,因为GRPC只能连接某个固定IP,所以实际使用的时候需要和etcd或者zookeeper结合封装

server端在etcd上注册服务路径

client端在etcd的服务路径上获取server的IP,选取其中一个来访问。

实际的使用可能是这样

//s中包含了grpc.Server s = service.NewServer() test.RegisterTestServer(s.grpcServer,&testServer{}) //用grpc监听端口,并且将IP端口注册在etcd的Path上 s.Listen("ip:port","etcdURL+Path")

1

//etcd的服务路径上获取server的IP,全部建立连接 s = service.NewClientManager("etcdURL+Path") //随机获取一个conn来连接 c = test.NewTestClient(s.GetConn()) c.Test1(context.Background(),&test.TestRequest{}) ```

还有更加复杂的情况

例如一个主从系统的实现

总结在下一篇博客好了