


























主要是两个文档, grpc repo的文档 https://github.com/grpc/grpc/tree/master/doc , grpc-go repo的文档 https://github.com/grpc/grpc-go/tree/master/Documentation.
在代码中import "google.golang.org/grpc/reflection"包, 然后加一行代码reflection.Register(s), 就可以启用 server reflection. 就可以用grpc_cli去进行获得服务列表, 方法列表, message结构体定义了. reflection.Register(s)实际上是注册了一个特殊的service, 它能列出server中已注册的服务和方法等信息.
用 encoding.RegisterCompressor方法取注册一个压缩器, 启用了压缩的话, 服务端和客户端双方都要进行同样的处理, 服务端在newServer时要带上compressor的serverOption, 客户端在dail的时候要带上WithDefaultCallOptions的DialOption, DialOption加上压缩解压的处理, 不然会得到一个 Internal error, 和HTTP方式一样, 压缩类型体现在content-type的header上.
Dial得到的ClientConn是并发安全.
stream的读写不是并发安全的, sendMsg或RecvMsg不能在多个goroutine中并发地调用,但可以分别在两个goroutine中处理send和Recv.
自定义消息编码解码, 注册一个实现 Codec 接口的对象即可, 然后在Dial或Call时带上grpc.CallContentSubtype这个CallOption, 这样就可以自动处理这个带这个content-type的请求. 默认为 proto
自定义压缩解压缩, 注册一个实现 Compressor接口的对象即可, 然后在Dial或Call时带上grpc.UseCompressor这个CallOption.
](https://github.com/grpc/grpc-go/blob/master/Documentation/gomock-example.md)
主要讲如何在单元测试中mock, 用gomock命令行生成实现xx接口的代码, 没什么特别的
](https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-auth-support.md)
主要讲如何进行身份验证, 没什么特别的
metadata类似HTTP1中的header, 数据结构都是一样的type MD map[string][]string,
key都是大小写不敏感的, 但实现规范和HTTP1不一样, HTTP1是按单词之间用连字符”-“分隔, 每个单词第一个字母大写这样的规范来的, 处理起来消耗更大, 而metadata是全转为小写, 实际使用过程中, 提前规范化key能提高不必要的strings.ToLower调用.
用-bin结尾的来传递二进制数据.
服务端handler用metadata.FromIncomingContext(ctx)拿到metadata, 客户端用metadata.AppendToOutgoingContext来附加kv到ctx中.
如果服务端handler又想附加一些信息返回client, 那么就要通过header和trailer传递, 类似responseHeader.
func (s *server) SomeRPC(ctx context.Context, in *pb.someRequest) (*pb.someResponse, error) {
// create and send header
header := metadata.Pairs("header-key", "val")
grpc.SendHeader(ctx, header)
// create and set trailer
trailer := metadata.Pairs("trailer-key", "val")
grpc.SetTrailer(ctx, trailer)
}
然后客户端在调用的时候传要保存的header和trailler的指针到CallOption中, 调用完后指针指向的metadata map就有数据了, 坦率地讲, 我觉得这样处理很麻烦.
var header, trailer metadata.MD // variable to store header and trailer
r, err := client.SomeRPC(
ctx,
someRequest,
grpc.Header(&header), // will retrieve header
grpc.Trailer(&trailer), // will retrieve trailer
)
// do something with header and trailer
gRPC会定时发http2 ping帧来判断连接是否挂掉, 如果ping没有在一定时期内ack, 那么连接会被close.
grpc-go包默认用gpclog包打日志, grpclog包默认是用多个*log.Logger来实现日志级别, 默认输出到stderr, 对于生产环境, 肯定要集成到自己的日志流里去, 接口是个好东西, grpclog包允许setLog, 实现grpclog.LoggerV2接口即可.
grpclog里的info是为了debug
之前一直有个误区, 多个连接比单个连接要快, 看了 grpc-go issues1、grpc-go issues2 以及 HTTP2文档 才发现, 由于HTTP2有多路复用的特性, 对于同一个sever, 只需要维护一个连接就好了, 没有必要用多个连接去并行复用数据流. 连接数量减少对提升 HTTPS 部署的性能来说是一项特别重要的功能:可以减少开销较大的 TLS 连接数、提升会话重用率,以及从整体上减少所需的客户端和服务器资源。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。