目录

Go GRPC使用

1.1RPC简介

RPC,全称 Remote Procedure Call——远程过程调用,主要用于分布式系统中程序间的通信,基于 TCP 或 UDP 传输协议实现。RPC 属于 IPC(进程间通信)的分支,除 RPC 外还有共享内存、channel 等。

GRPC 是谷歌开源的一个高性能、跨语言的 RPC 框架,基于 HTTP2 、Protobuf 和 Netty 4.x ; GRPC 的优势不在于性能,而是跨语言,还和 Golang 有同一个爹。。。

GRPC 官网:https://grpc.io/

1.2  Protobuf 简介

Google Protocol Buffer(简称 Protobuf)是一种轻便高效的结构化数据存储格式,平台无关、语言无关、可扩展,可用于通讯协议和数据存储等领域。

简言之,这是一种跨语言的结构化数据存储格式,类似于 JSON

官网:https://developers.google.cn/protocol-buffers/docs/proto3

中文文档:http://doc.oschina.net/grpc?t=56831

1.3 protobuf 安装

官方教程:https://github.com/protocolbuffers/protobuf/blob/master/src/README.md

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ sudo apt-get install autoconf automake libtool curl make g++ unzip
$ git clone https://github.com/google/protobuf.git
$ cd protobuf
$ git submodule update --init --recursive
$ ./autogen.sh
$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig # refresh shared library cache.

安装完成后输入:protoc –version 查看版本信息

Go语言 Protobuf 编译

Go语言版 grpc下载:

$ go get -u google.golang.org/grpc

若由于网络问题无法下载,使用 github 镜像再将包移动到 google.golang.org:

$ go get -u github.com/grpc/grpc-go

Go语言 proto 编译环境:

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

同理…使用了很多 golang.org/ 包,镜像下载参考:[Go 下载包 golang.org/x/][1]

1.4 实战使用

定义 proto

新建 user.proto 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
syntax = "proto3"; //Protocol Buffers Version
//定义的service
service CreateAccount{
    rpc CreateAccount(CreateAccountRequest) returns (CreateRequestResponse){}
}
//请求的结构体
message CreateAccountRequest{
    string uid = 1;
    string service = 2;
}
//返回的结构体
message CreateRequestResponse{
    string value = 1;
}

编译 Go 源码,生成user.pb.go(将package user改为 hello)

$ protoc --go_out=plugins=grpc:. hello.proto

Go 客户端

新建userClient.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
func CreateAccount(uid string, service string) (value string, err error){
	conn, err := grpc.Dial("localhost:1330", grpc.WithInsecure())
	if err != nil {
		fmt.Println(err)
		return "error", err
	}
	defer conn.Close()
	client := hello.NewCreateAccountClient(conn)
	Value, err := client.CreateAccount(context.Background(), &hello.CreateAccountRequest{Uid:uid,Service:service})
	if err != nil {
		fmt.Println(err)
		return "error", err
	}
	return Value.Value,nil
}

Go服务端

新建userServer.go

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
type server struct{}
func (s *server) CreateAccount(ctx context.Context,response *hello.CreateAccountRequest) (*hello.CreateRequestResponse, error){
	fmt.Println(response.Uid+response.Service)
	return &hello.CreateRequestResponse{Value:"hello =======> " + response.Uid},nil
}
func main(){
	lis,err := net.Listen("tcp","1330")
	if err != nil {
		log.Fatal("fail to listen")
	}
	s := grpc.NewServer()
	hello.RegisterCreateAccountServer(s,&server{})
	reflection.Register(s)
	if err:= s.Serve(lis);err != nil{
		log.Fatal("fail to server")
	}
}

调用

开启 server 端保持监听端口1330状态,调用CreateAccount()函数传值即可。