1. 为什么说 Service Mesh 是下一代微服务架构?

目前大部分互联网公司构建微服务体系的框架,还是会首选 Java 的 SpringCloud,因为它完整的生态体系。

在了解 Service Mesh 之前,我们先看一下使用 SpringCloud 构建微服务体系的大致流程:

  • 实现服务注册、服务发现
    • 首先需要独立部署一款实现 服务注册/服务发现 功能的组件服务,目前可供选择的主流方案一般有 Eureka、Consul、Nacos 等;
    • 然后需要将微服务注册到服务注册中心,在我们编写的 business service 微服务中,引入 SpringCloud 提供支持对应注册中心接入的 SDK,并在应用入口类中通过 @EnableDiscoveryClient 注解的方式标注,之后 SDK 中的逻辑就会在应用启动时执行服务注册动作,并提供给注册中心相应地探测接口,以此实现微服务与服务注册中心之间的连接。以此类推,我们可以通过这种方式将一组微服务都注册到服务注册中心!
  • 实现服务之间的互相调用、负载均衡
    • 一般我们会通过编写 FeignClient 接口来实现微服务之间的调用,而其底层的逻辑则是通过 Feign 所集成的 Ribbon 组件去注册中心中获取目标服务的服务地址列表,之后 Ribbon 根据服务地址列表进行负载均衡调用。至于服务与注册中心之间如何保证连接有效性,则依赖于服务注册中心与其 SDK 之间的协作机制。
  • 实现服务熔断限流
    • 可以通过部署服务网关组件(例如 Zuul/Spring Cloud GateWay)来实现微服务入口的熔断限流、内部服务之间的限流熔断则通过集成 Hystrix 或 Sentinel 组件

仔细回顾使用 SpringCloud 构建微服务的大致过程,会发现:

  • 与服务治理相关的大部分逻辑都是以 SDK 的方式耦合在具体的微服务应用之中!服务注册需要引入 SDK、服务调用需要引入 SDK、服务熔断限流需要 SDK;
  • 除此之外,为了保证这套体系的正常运行,我们还需要额外维护一些基础服务:注册中心、服务网关等;

SpringCloud 这样的微服务设计结构会导致什么弊端呢?具体有以下几点:

  • SDK 太多,后续升级维护困难
    • 在这套体系中,与服务治理相关的逻辑都是以 SDK 代码依赖的方式嵌入在微服务之中,如果某天我们想升级下服务注册中心的 SDK 版本,或者熔断限流组件 Hystrix 或 Sentinel 的版本,那么需要升级改造的微服务可能会是成百上千,且由于这些组件都与业务应用绑定在一起,在升级的过程中会不会影响业务稳定,这都是需要谨慎对待的事情,所以对 SDK 的升级难度可想而知的!
  • 多语言微服务 SDK 维护成本高
    • 如果构建的微服务体系,也要支持像 Go、Python 或者其他语言编写的微服务的话,那么上述这些微服务治理相关的 SDK 是不是得单独再维护几套呢?所以在这种体系结构中,对多语言微服务的支持就成了一个问题!
  • 服务治理策略难以统一控制
    • 基于该套体系构建的微服务体系,在对像熔断、限流、负载均衡等服务治理相关的策略管理上,都是比较分散的,可能有人会写到自己的本地配置文件,有人会硬编码到代码逻辑中,也可能有人会将其配置到远程配置中心,总之对于服务治理策略逻辑都是由对应的开发人员自己控制,这样就很难形成统一的控制体系!
  • 服务治理逻辑嵌入业务应用,占有业务服务资源
    • 在这套微服务体系中,服务治理相关的逻辑都是在微服务应用进程中寄生运行的,这多少会占有宝贵的业务服务器资源,影响应用性能的发挥!
  • 额外的服务治理组件的维护成本
    • 无论是服务注册中心、还是服务网关,这些除了微服务应用本身之外服务治理组件,都需要我们以中间件基础服务的方式进行维护,需要额外的人力、额外的服务器成本!

在像基于类似 SpringCloud 这样的微服务框架基础之上构建的第一代微服务体系,通常都会具有以上这些弊端。而在设计理念上与传统微服务体系有很大差异的 Service Mesh 体系下,就不存在以上问题,甚至都不需要研发人员再进行任何关注。我们只需要写一个普通的 SpringBoot 服务,也不再需要引入各种基础服务对应 SDK (服务注册、熔断限流等),就能实现像之前 SpringCloud 微服务体系所能支持的大部分服务治理功能。

我们称之为下一代微服务架构的 Service Mesh,它的设计结构解决了传统微服务体系的大部分弊端,它的目标就是要将微服务治理体系下沉为一套与业务无关的基础设施。像传统的 SpringCloud 体系好歹能够让我们感知下微服务的存在,而在 Service Mesh 中,微服务治理体系将作为基础设施的一部分,对普通研发人员将越来越透明!

2. Service Mesh 的解决方案是什么?

在前面我们说到,Service Mesh 的目标是要将微服务治理体系下沉为与业务无关的基础设施。这句话怎么理解呢?实际上 Service Mesh 微服务治理技术的诞生也不是凭空产生的,而是在以 Kubernetes 为代表的容器编排技术逐步成为软件运行主流基础环境的背景下,以及以 Spring Cloud 框架为代表的传统微服务技术体系弊端逐步显现的情况下技术自然迭代发展的结果。总之,就是有点万事具备,只欠东风的感觉!

所以,我们看到目前落地的 Service Mesh 方案中大多都是与 Kubernetes 深度结合的方案,例如最受瞩目的 Istio!接下来我们具体看看在 Service Mesh 中微服务治理的核心逻辑是怎么实现的(以 Istio+Envoy 为例)!
image.png
Service Mesh 的概念由来:
其中绿色的正方形表示正常部署的微服务,而蓝色的正方形表示一个网络代理,也就是大家通常所说的 SideCar。在 Service Mesh 架构下,每部署一个微服务,都需要部署一个与之相对应的代理服务,所有与微服务本身的交互都通过 SideCar 代理,而 SideCar 之间会形成一张形似网格的交互链路,这就是服务网格名称的来由!

在 Service Mesh 中,当我们将一个服务部署在 Kubernetes 之后,安装在 Kubernetes 中的 Service Mesh 组件(例如 Istio)就会自动在该微服务的同一个 Pod 之中启动一个与之对应的代理进程(例如 istio-proxy),这个保姆式的代理进程会代替微服务本身去实现原先在 Spring Cloud 体系中需要微服务自身完成的服务注册、负载均衡、熔断限流等微服务治理功能。并且,这些代理进程并不是孤军奋战,而是会通过像 xDS 协议(Service Mesh 中数据面与控制面通信的通用协议)与 Service Mesh 控制组件保持连接。

这也就引出了 Service Mesh 架构中关键的两个概念:控制面与数据面。

  • 前面我们所示的 Sidecar(例如 istio-proxy,实际上是 envoy)就是数据面,与微服务治理逻辑相关的信息都存储在数据面中;
  • 而控制面则是 Service Mesh 的中心控制组件(例如 Istio 中的 Pilot 组件),控制面可以通过 xDS 协议(具体又分为 LDS、CDS……)向数据面下发各种服务治理相关的规则,例如限流规则、路由规则、服务节点更新信息等等。

这种设计方式就是 Service Mesh 最核心的设计逻辑——通过 Sidecar 的方式代理微服务进行服务治理逻辑(数据面),通过控制面感知外界环境的变化并通过 xDS 协议支持各种微服务治理策略规则的集中管理和下发,而这里的控制面和数据面都会被融合进像 Kubernetes 这样的基础架构环境中,对于普通微服务的开发,研发人员要做的只是将一个应用以编排的方式部署进 Kubernetes 集群即可!而所有与微服务治理相关的逻辑都由代理数据面与控制面协作完成。

3. Service Mesh 明星项目

image.png
Service Mesh 是最早 2016 年就被提出,然后在 2018 年才开始较大规模的被人了解。

目前 Service Mesh 这一领域大部分只是开源项目,还没有比较现成的商业产品,比较知名的项目有:

  • Linkerd:2016 年发布,是这些项目中最老的。Linkerd 是从 Twitter 开发的 library 中分离出来的。在这一领域另一位重量型选手,Conduit,已经进入了 Linkerd 项目并构成了 Linkerd 2.0 的基础。
  • Envoy:由 Lyft 创建,为了能够提供完整的 Service Mesh 功能,Envoy 占据“数据平面”的部分,与其进行匹配。
  • Istio:由 Lyft、IBM 与 Google 联合开发,Istio 可以在不修改微服务源代码的情况下,轻松为其加上如负载均衡、身份验证等功能,它可以通过控制 Envoy 等代理服务来控制所有的流量。此外,Istio 提供容错、金丝雀部署、A/B 测试、监控等功能,并且支持自定义的组件和集成。
  • HashiCorp Consul:与 Consul 1.2 一起推出了一项名为 Connect 的功能,为 HashiCorp 的分布式系统添加了服务加密和基于身份的授权,可用于服务发现和配置。

目前,Linkerd 和 Istio 包含最丰富的功能集,但一切都还在迅速发展中。

参考:https://mp.weixin.qq.com/s/VfShSkK-2mJShdp2a_AjjQ