学学 grpc-go,顺便整整优化
简单应答服务
安装idl转换工具
1 | go install google.golang.org/protobuf/cmd/protoc-gen-go |
然后写一份proto
1 | // 注意要是 proto3 ,只有3才支持 service 语法 |
编写完进入代码路径,执行
1 | protoc.exe --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative .\server.proto |
就可以生成 *.pb.go
和 *_grpc.pb.go
两个源码文件,接下来实现相关方法。
1 | import ( |
实现加入的 repo.UnimplementedGreeterServer
,是grpc-go后面版本新增加的,默认实现了所有接口的对象。默认方法是返回一个错误,显示接口未实现,保证主调方用新pb调用服务端旧协议时,出现奇怪的错误。
1 | // GreeterServer is the server API for Greeter service. |
接下来就是监听并服务了。grpc有两种监听方式,一种是直接listen一个tcp socket,另外一种是通过 ServeHTTP
,和http server 一起工作。下面是直接listen tcp的实现
1 | package main |
客户端
1 | package main |
到这里,一个简单的 Echo 服务就搭好了。
这里不难看出,每次都是Dial一个新的链接,然后发起请求,并没有复用链接,所以其实有优化空间。
流式服务
在pb的 request 和 response 前面加个 stream ,就是流接口定义
1 | service Greeter { |
服务端新增个接口实现
1 | func (*GreeterImpl) StreamEcho(s repo.Greeter_StreamEchoServer) error { |
client 写个循环 recv
1 | c, err := client.StreamEcho(context.Background()) |
配合nginx
一般会用nginx或其他工具作为中间层,tls加密放在中间层,所以grpc服务这边可以使用非加密的h2c提供服务
1 | func main() { |