微服务架构与云原生

目录

微服务架构与云原生

从微服务架构的思想,我们可以感受到微服务架构、DevOps 和容器技术自然地走到了一起,构成了云原生应用架构的雏形。

在这里插入图片描述

在这里插入图片描述

在云原生时代,微服务的特点:

  • 平台化:利用云作为一个平台,为微服务架构进行更多的赋能。
  • 标准化:我们希望微服务本身的部署、运维,微服务之间与其它服务之间的通讯都能做到标准化,让服务与服务之间的互联互通变得更容易,服务能够跨到不同的平台上,做到一次编写、一次定义、多处运行。
  • 微服务轻量化:让研发人员关心核心业务代码、业务逻辑的研发,而不是复杂的微服务治理相关的逻辑研发。
  • 微服务的产品化:希望能构建微服务相关的产品,以产品化的方式支持大家使用微服务架构,让它变得更好用、更易用。

微服务架构首先要面对分布式架构的内生复杂性。微服务框架需要能够解决服务通信和服务治理的复杂性,比如服务发现、熔断、限流、全链路追踪等挑战。

微服务框架,如 HSF/Dubbo 或 Spring Cloud 以代码库的方式来封装这些能力。这些代码库被构建在应用程序本身中,随着应用一起发布和维护。

在这里插入图片描述

服务通信和治理本质是横向的系统级关注,是与业务逻辑正交的。但在微服务架构中,其实现方式和生命周期与业务逻辑耦合在一起的。

微服务框架的升级会导致整个服务应用的重新构建和部署。此外由于代码库通常与特定语言所绑定,难以支持企业应用的多语言(polyglot)实现。

SOA 采用中心化的服务总线架构,解耦了业务逻辑和服务治理逻辑;微服务架构回归了去中心化的点对点调用方式,在提升敏捷性和可伸缩性的同时,也牺牲了业务逻辑和服务治理逻辑解耦所带来的灵活性。

为了解决上述挑战,社区提出了 Service Mesh(服务网格)架构。它重新将服务治理能力下沉到基础设施,在服务的消费者和提供者两侧以独立进程的方式部署。

这样既达到了去中心化的目的,保障了系统的可伸缩性;也实现了服务治理和业务逻辑的解耦,二者可以独立演进不相互干扰,提升了整体架构演进的灵活性。同时服务网格架构减少了对业务逻辑的侵入性,降低了多语言支持的复杂性。

在这里插入图片描述

Google, IBM,Lyft 主导发起的 Istio 项目就是服务网格架构的一个典型的实现,也成为了新的现象级 “网红” 项目。

在这里插入图片描述

上图是 Istio 的架构,逻辑上分为数据平面和控制平面:

  • 数据平面由一组以 sidecar 方式部署的智能代理组成,负责截获应用网络流量,收集遥测数据并且执行服务治理策略;
  • 控制平面中,Galley 负责配置管理,Pilot 负责下发配置,Mixer 负责策略检查和遥测数据聚合,Citadel 负责通信中安全证书管理。

Istio 提供了一系列高阶的服务治理能力,比如:服务发现和负载均衡,渐进式交付(灰度发布),混沌注入与分析,全链路追踪,零信任网络安全等,可以供上层业务系统将其编排到自己的 IT 架构和发布系统之中。

但是 Service Mesh 不是银弹,其架构选择是通过增加部署复杂性(sidecar)和损失性能(增加两跳),来换取架构的灵活性和系统的可演化性。

为了解决部署复杂性的挑战,社区和云服务商都在共同进行努力:

  • 一方面简化服务网格自动化运维水平(比如阿里云通过 operator 大大简化了 Istio的升级运维和跨 K8s 集群部署的复杂度);
  • 另一方面提供托管的服务网格服务,帮助用户关注在业务层面的服务治理而非基础架构实现。

关于性能问题:

  • 一方面 Service Mesh 需要降低自身控制平面和服务平面的性能开销,比如尽可能 offload mixer 负载,将治理策略执行下沉到数据平面完成;
  • 另一方面还需要重新思考整个通信栈中应用与网络基础设施的边界。

为了实现容器应用之间的互联互通,Kubernetes 社区提出 CNI 网络模型,将容器网络连通性与底层网络实现的进行解耦,同时 K8s 提供了 Service, Ingress, Network policy 等基本元语来支持应用层的服务通信和访问控制。但是这些能力远不能满足应用对服务治理的需求。

服务网格在 L4/L7 增加了流量管理、全链路可观测性、安全互联等新功能,这些是通过引入运行在用户空间的 Envoy 代理实现的,在提升灵活性的同时也不可避免地增加了性能开销。

为了系统化解决这个问题,社区在进行有趣的探索。比如在 Cillium 容器网络中,可以利用 eBPF/XDP 等操作系统和底层网络能力,将应用层的服务控制能力(如 Kube-Proxy 提供的 service, network policy)下沉到操作系统内核和网络层解决,并优化了 Service Mesh 数据链路,减少上下文切换和数据拷贝,有效地减少了性能开销。

在这里插入图片描述

目前 Service Mesh 技术还处在技术成熟度曲线的初期,除了在 L4/L7 层提供灵活的服务通信功能,社区也在探索通过网络 Service Mesh[6] 实现灵活的 L2/L3 组网能力。我们相信其会成为未来企业分布式应用通信基础设施。

在这个过程中会有一些新的理念和项目被持续创造出来,我们需要能够理性地分析其业务价值和技术局限性。我们要避免将 Service Mesh 作为万灵药,不要将应用集成、应用侧安全等业务逻辑下沉到服务网格中,避免我们重蹈复杂性覆辙。

Service Mesh

另一种抽象公共代码的方法是直接将这些代码抽象到一个反向代理组件。每个服务都额外部署这个代理组件,所有出站入站的流量都通过该组件进行处理和转发。这个组件被称为Sidecar。

Sidecar不会产生额外网络成本。Sidecar会和微服务节点部署在同一台主机上并且共用相同的虚拟网卡。所以Sidecar和微服务节点的通信实际上都只是通过内存拷贝实现的。

在这里插入图片描述

Sidecar只负责网络通信。还需要有个组件来统一管理所有sidecar的配置。在Service Mesh中,负责网络通信的部分叫数据平面(data plane),负责配置管理的部分叫控制平面(control plane)。数据平面和控制平面构成了Service Mesh的基本架构。

在这里插入图片描述

Sevice Mesh相比于微服务框架的优点在于它不侵入代码,升级和维护更方便。它经常被诟病的则是性能问题。即使回环网络不会产生实际的网络请求,但仍然有内存拷贝的额外成本。另外有一些集中式的流量处理也会影响性能。

流量治理

微服务一方面是把原来在静态编译时产生的能力与能力之间的关联关系,通过架构拆分推演到动态的运行时。因此在运行时,服务与服务之间是需要进行通讯、协同,才能完成某一项具体的业务功能。当大家进行通讯、协同时,就一定要对其通讯过程进行管理,或者说要进行流量管理。例如,我们要知道怎样从一个微服务找到另一个微服务,以及怎样能保证一个微服务找到最佳的微服务实例跟它进行通讯,这是一个比较复杂的过程,其中包括 RPC 能力、服务注册发现能力、动态配置管理能力以及服务降级能力等等。

为了减轻业务开发同学的负担,不用重复的在每一个微服务中写一遍微服务的流量管理的通用能力,因此大家开发了很多框架,比如在 Java 体系中,著名的 Spring Cloud 提供了一个分布式微服务管理框架;在 Go 语言的开源生态中也有像 Go Mirco 这样的体系;在阿里巴巴内部我们也有像 HSF 这样的体系发展起来的微服务治理框架。

在这里插入图片描述

因此,从抽象层面可以看到一个服务包含了两个层面:

在这里插入图片描述

一个层面是本身的业务逻辑,也就是由微服务业务开发人员去编写的,功能实现与业务实现相关的代码。

另一个层面是为了实现微服务与微服务之间通讯、流量、服务治理的代码,我们会将其抽象成一个框架,如下图中标出的 Spring Cloud。这样的抽象带来了一个问题,就是所有的通用能力都依赖于这个具体的框架。

在这里插入图片描述

假设在公司之中,除了 Spring Cloud 之外,我们去引入另外一些服务框架,如阿里巴巴 HSF 如果希望和 Spring Cloud 框架上面编写的微服务进行通讯的话应该如何去操作?这就要求 HSF 与 Spring Cloud 之间互联互通以及协议之间的互相理解。但其实这些框架之间往往并不具备这个能力。更大的一个问题可能在于,云原生时代我们允许这些微服务的研发能用不同开发语言及模型来进行编程。因此,框架之间的系统并不是不是一对二的关系,也不是 仅仅是 Spring Cloud 与 HSF 的关系,可能是 Java 体系与 JavaScript、Python、Go 体系这些微服务框架都需要打通的问题,它变成了一个 N to M 的 problem,来解决多语言、复杂环境中微服务的治理与管理问题。

这时,当我们有了容器、容器平台、Pod 这些抽象,能够提供一个平台,而不是必须要完全依赖于业务中的代码或 框架时,有没有更好的办法来解决刚才提到的问题?

在这里插入图片描述

现在有一个比较流行的概念叫 Service Mesh——服务网格。它的本质就是为了更好地解决流量治理在多语言、多环境场景下的问题,它的主要思想如下:

  • 第一就是希望把流量管理的这些框架能力从耦合在业务的二进制中抽象、剥离出来,形成一个流量管理的单独进程,并以 Sidecar 的模式部署在 Pod 中。通过操作系统级别的透明流量劫持工作,把所有的微服务之间的流量劫持到 Sidecar 中,然后通过 Sidecar 与 Sidecar 之间通讯进行流量的转发与管理。这样问题就简单多了,我们只需要让流量管理的 Sidecar 之间互相通讯、能够进行互联互通。目前比较知名、流行的开源流量劫持和管理 Sidecar 实现叫做 Envoy。

当然,单单有了这层流量劫持与管理还是不够的,还需要管控平面的支持。比如原来微服务体系做的服务注册、服务发现以及流量观测还是需要的,这些策略和规则需要下发给流量管理的 Sidecar 代理。因此,我们还需要构建一个管控平面来管理在 Pod 中部署的流量管理的数据平面的单点,让它们形成一个网状,形成一个集群。所以我们需要有一些管控平面的能力,在开源中比较流行的一个管控平面实现叫 Istio。主要实现了三个能力:流量的配置、流量的安全、流量的观测。

我们认为在云原生这个逐渐平台化的时代,大部分新的应用及场景都会尝试选用基于 Service Mesh 的技术进行微服务的流量治理。

猜你喜欢

转载自blog.csdn.net/Jmilk/article/details/108434052