架构

 

arch

  1. 前端通过REST经过网关访问接入层应用
  2. 网关实现接口转换 ( gRPC -> REST ) | 相对麻烦
  3. 后端服务之间使用gRPC进行调用

 

gRPC服务注册与发现方案

问题:当服务发生变化(部署、扩容、缩容等)时,服务之间的通讯线路如何更新。

pb

对于简单的C/S调用我们可以直接写死访问地址:

但是在随时都会发生服务地址变化的微服务环境,这种方式就不适用了。

DNS

dns

DNS实现的负载均衡是gRPC默认支持的

 

过程原理: 服务启动/关闭的时候,系统会更新内部DNS,使得域名解析返回所有的相应服务地址(A记录)。gRPC客户端使用域名进行访问。

负载均衡:

访问的过程有点复杂,具体来说,gRPC默认有三个负载策略: grpclbpick_firstround_robin

当返回地址有声明lb地址时,执行grpclb策略,这里我们就不关心了。

对于大部分情况,DNS返回所有服务器的地址记录,gRPC默认采用 pick_first即选择A记录中的第一条记录作为访问目标。 显然这不是我们想要的,虽然没有太多负载算法可以选择,但是round_robin可以满足大部分的需求(用户可以自行扩展gRPC的API):

实现方案:

 

注册中心

sd

过程原理: 服务应用启动时,将自己的元信息(IP地址、端口、心跳检测、标签等)注册到注册中心,访问端需要访问服务时,向注册中心查找相应服务的地址。

负载均衡:

无,应用获取地址后,自行选择调用策略。

实现方案:

这是大部分微服务注册/发现中心的主要方式

 

通用LB

lb

过程原理: 应用之间通过中央代理服务器相互访问,负载均衡器(Nginx、Haproxy等)通过读取服务注册中心(或K8S),自动更新配置和上游服务器。| 对于传统架构,这种方式运行良好,但是对于N对M的微服务架构来说,这种方式容易形成瓶颈和单点故障

负载均衡:

支持完全自定义,毕竟其本身就是专业的负载均衡了嘛....

实现方案:

Kubernetes的内部Ingress、consul-template读取consul并刷新Nginx配置也都是这方面的例子,可以理解为内部服务网关。

Service Mesh

mesh

过程原理: 每个服务附带一个网络代理服务,网络代理服务接管访问流量,服务只需要直接访问附带的代理服务即可,其他问题由代理服务解决。控制平面(Istio、Linkerd、Consul等)会管理所有的代理服务,通过它们实现网络管理,包括负载均衡、健康检查、加密、mTLS等各种功能。 | 这种方式很强大,未来可期,不过对于目前,这种架构略显复杂

负载均衡:

自定义

实现方案:

Consul

Consul支持上面所有的方式,包括基于API的服务注册/发现、基于DNS和基于Service Mesh的方式。