我们先看看GRPC这个项目的总览,主要分三种:
从这里可以看出,gRPC虽然是支持多语言,但原生的实现并不多。如果想在一些小众语言里引入gRPC,还是有很大风险的,有兴趣的可以搜索下TiDB在探索rust的gRPC的经验分享。
作为一名Go语言开发者,我自然选择从最熟悉的语言入手。同时,值得注意的是,grpc-go是除了C家族系列
以外使用量最大的repo,加上Go语言优秀的可读性,是一个很好的入门gRPC的阅读材料。
进入项目,整个README.md文档也不长。通常情况下,如果你能啃完这个文档及相关链接,你对这个开源项目就已经超过99%的人了。
对Repo的相关注意事项,大家逐行阅读即可,整体比较简单,我简单列举下关键点:
通读完成,我们再深入看看文档细节,Example这块我们在官网的测试中已经看过,我们的接下来重点是godoc和具体细节的文档。
注意,这个变量被弃用,被挪到 ConnectParams
里了(详情链接)。那这个所谓的连接参数是什么用呢?代码不长,我们选择几个比较重要的内容来阅读下,原链接可以点击这里。
// Backoff returns the amount of time to wait before the next retry given the
// number of retries.
// 根据retries返回等待时间,可以认为是一种退避策略
func (bc Exponential) Backoff(retries int) time.Duration {
if retries == 0 {
// 之前没有retries过,就返回BaseDelay
return bc.Config.BaseDelay
}
backoff, max := float64(bc.Config.BaseDelay), float64(bc.Config.MaxDelay)
// 等待时间不能超过max,等待时间 = BaseDelay * Multiplier的retries次方
// Multiplier默认1.6,并不是官方http包中的2
for backoff < max && retries > 0 {
backoff *= bc.Config.Multiplier
retries--
}
if backoff > max {
backoff = max
}
// Randomize backoff delays so that if a cluster of requests start at
// the same time, they won‘t operate in lockstep.
// 乘以一个随机因子,数值为(1-Jitter,1+Jitter),默认为(0.8,1.2),防止同一时刻有大量请求发出,引起锁的问题
backoff *= 1 + bc.Config.Jitter*(grpcrand.Float64()*2-1)
if backoff < 0 {
return 0
}
return time.Duration(backoff)
}
用来设置是否开启 trace,追踪日志
gRPC的错误码,原代码见链接,我们大概了解其原因即可:
读完上面的内容,发现跟HTTP/1.1的Status Code非常相似。
调用在客户端 Invoke
方法中,包括before发送前,after为接收后。
官方提供了几个常用的CallOption,按场景调用。
抽象的客户端连接。
值得注意的是,conns是一个map,所以实际可能有多个tcp连接。
定义了Marshal和Unmarshal的接口,在grpc底层实现是proto,详细可见 codec
压缩相关的定义
元数据,也就是key-value,可以类比到http的header
客户端新建连接时的选项,按场景调用。
服务端监听时的选项,按场景调用。
性能测试,有兴趣的可以细看gRPC是从哪几个维度做RPC性能测试的。
可用encoding.RegisterCompressor实现自定义的压缩方法。
注意,压缩算法应用于客户端和服务端两侧。
支持并发,从三个角度分析:
ClientConn
支持多个GoroutineSteams
中,SendMsg
/RecvMsg
可分别在两个Goroutine中运行,但任何一个方法运行在多个Goroutine上是不安全的Server
每个客户端的invoke会对应一个Server端的Goroutine类似Compression,可用encoding.RegisterCodec实现自定义的序列化方法。
用mock生成测试代码,详细可细看。
认证的相关选项,包括 TLS/OAuth2/GCE/JWT ,一般用前两者即可。
介绍了Metadata的使用,类比于HTTP/1.1的Header。
长连接的参数分为3类:
四个级别的log level,针对不同场景:
Info
用于debug问题Warning
排查非关键性的问题Error
gRPC调用出现无法返回到客户端的问题Fatal
导致程序无法恢复的致命问题使用默认的HTTP或HTTPS代理。
结合官方提供的错误码,用 status.New
或者 status.Error
创建错误。
服务端方法映射,跟着教程走即可。
值得一提的是,采用c++中的grpc_cli模块,可以查看指定端口暴露出来的服务详情。
版本演进,一般情况下每6周一个小版本,紧急修复会打补丁号。
gRPC源码分析(三):从Github文档了解gRPC的项目细节
原文:https://www.cnblogs.com/cx2016/p/13817099.html