为什么要应用gRPC?
在云原生的背景下,微服务大行其道。拆分的服务越来越细粒度,绝对于之前的单体架构设计,服务之间通信的品质成为影响整体服务质量的一个重要环节。
此外当初的研发体系,很少只存在一种语言,往往是多语言。此时,解决多语言交互也是一个必须解决的问题。
gRPC (gRPC Remote Procedure Calls) 是Google发动的一个开源近程过程调用 (Remote procedure call) 零碎。该零碎基于 HTTP/2 协定传输,应用Protocol Buffers 作为接口描述语言。
其余性能:
- 认证( authentication)
- 双向流(bidirectional streaming)
- 流控制(flow control)
- 超时(timeouts)
最常见的利用场景是:
- 微服务框架下,多种语言服务之间的高效交互。
- 将手机服务、浏览器连贯至后盾
- 产生高效的客户端库
然而运行gRPC服务也带给咱们一些挑战,大多数是因为HTTP/2 复用链接。
gRPC带来的挑战
gRPC只是一个RPC通信框架,并不是一个服务治理框架。尤其在云原生的环境下,比方kubernetes中,因为资源缓和被驱赶,或是弹性伸缩等起因,客户端如何能及时感知到新增的server,以及剔除掉销毁的资源实例是一个挑战。因为HTTP/2 复用链接,如何解决负载平衡的问题也是另外一个挑战。
gRPC的负载平衡能够分为客户端负载平衡和代理负载平衡。
上面咱们讲下咱们理论应用过程中一些计划。
解决方案 1: 基于envoy的ingress controller
该计划又可称为边缘ingress。因为数据层envoy通过daemonset的形式部署到集群中,这样相当于每个node节点上部署了一个代理。边缘部署的形式,满足了高可用的要求。
如果A服务须要拜访B服务,那么创立B服务的ingress,拜访域名为http://b.service.com。
这种计划相当于代理的形式解决负载平衡。服务注册和发现利用了k8s原生的服务发现能力。
该计划的毛病是,一个envoy要解决node节点上所有的流量,可能会因为某个服务的流量问题,影响了其余的服务。
解决方案 2: gRPC client
拜访方须要集成对应语言的gRPC client。
利用了client 的客户端负载平衡的能力。不过这种计划,须要可能获取到B服务可用的server列表。
如何实现服务注册和发现那?
咱们能够为B服务,创立一个Headless service,而后拜访b.default.cluster.local ,coredns 会返回可用的Pod列表。
此时,将b.default.cluster.local 配置到gRPC client,客户端主动会通过dns,返回可用列表,用于客户端负载平衡。
该计划毛病是客户端引入了sdk,减少服务的复杂性。
解决方案 3: 将envoy 以 Sidecar 的模式部署
将envoy以Sidercar的模式部署,联合了前两种计划的劣势,客户端代码不必引入非业务逻辑的代码,每个sidecar 只解决本client的流量逻辑。
论断
除了负载平衡和服务发现,咱们还须要实现优雅退出,因为不论是dns服务发现,还是k8s原生服务发现,均有肯定的提早。
此时咱们能够简略利用Pod生命周期的pre-stop钩子。
解决方案1和解决方案3,除了解决了负载平衡的问题,还能通过envoy 裸露进去的metrics和access log,减少了服务的可察看性。
当然最终的解决方案,是一个残缺的service mesh计划。**