深入浅出云原生架构:服务编排和服务网格

时间:2021-09-25来源:栏目:网络营销

作者|斯里尼潘奇卡拉,马尔西奥埃斯特韦斯。翻译|平川规划|丁小雨。本系列的第一部分讨论了微服务、无服务器和容器化等技术趋势的架构演进和战略架构模式。当技术平台发生较...

作者|斯里尼潘奇卡拉,马尔西奥埃斯特韦斯。

翻译|平川

规划|丁小雨。

本系列的第一部分讨论了微服务、无服务器和容器化等技术趋势的架构演进和战略架构模式。当技术平台发生较大变化时,遵循松耦合、可扩展性和接口设计原则的架构将更加灵活。一个设计良好的解决方案会将业务逻辑与技术组件(随着时间的推移,这些组件将会过时)隔离开来,并经得起时间的考验。

第二部分重点介绍架构稳定性缺陷和反模式(如分布式单体和“死星架构”),从而说明平衡架构和技术稳定性的必要性。

第三部分讨论了服务交互在微服务架构中的重要性,分布式系统面临的典型挑战,以及服务编排和服务网格等高级架构模式如何帮助我们克服这些挑战。

微服务架构带来了很多好处,但也带来了一些挑战。我们将把这些挑战视为架构机会,并讨论如何通过服务编排来克服它们。

本文讨论的设计模式适用于AWS、VMware Tanzu应用服务(前Pivotal Cloud Foundry)或Kubernetes等云平台。但是你也可以在非云的基础设施中使用它们。

Kubernetes已经成为许多组织中事实上的云平台。服务网格框架为我们充分利用云中的Kubernetes提供了一个极好的方法,无论您现在正在使用Kubernetes还是计划在未来对其进行一些研究。本文将介绍服务网格如何帮助我们管理生产环境中的服务部署。

首先,让我们看看我们(作为程序员或架构师)在分布式应用程序架构中遇到的挑战。

一个

挑战1:筒仓开发。

下面是一个分布式系统的例子,说明了在基于服务的架构和云平台出现之前,传统应用面临的挑战。

图 1、筒仓式开发示例

在这个例子中,有两个客户端应用程序(App 1和App2)和三个业务服务(服务1、服务2和服务3)。应用1与服务1和服务2交互。应用2仅与服务2交互。服务2也与服务3交互。

让我们仔细分析一下App 1,看看这个应用会发生什么。

这个例子说明了在微服务出现之前典型的应用程序开发和部署,即使在今天,一些应用程序仍然使用这种设计。

图 2、应用程序和后台的服务功能

上面的示例应用程序包含关键业务逻辑,并混合了非业务逻辑任务,所有功能都嵌入在应用程序代码中:

非功能性:验证、授权、通知等。

常见的平台任务:服务路由、服务发现、服务重试/断路器、跟踪等。

通常,非功能性需求被硬编码到应用程序中,并与业务逻辑混合,尽管这是许多应用程序共同关心的问题。

这个例子展示了一个传统应用程序包含多少真实的业务代码。相反,非功能性任务应该在应用程序之外处理,并由多个业务应用程序使用。

八个功能中只有一个是应用特定逻辑,其他七个功能不应该与应用逻辑耦合。

如果你仔细观察其他应用程序,你可能会发现同样的问题。

从服务1、2和3中可以看到类似的模式。每个服务的业务逻辑都混合了非功能性的平台任务,正如我们前面看到的,这些任务不应该包含在服务中。我们已经看到了一些常见的非功能性服务,比如身份验证、授权、客户通知等等。还有一些所有业务应用通用的平台服务,如路由、服务发现、服务监控和跟踪,都托管在云平台上。当我们仔细查看每个组件时,这个包含2个应用程序和3个服务的分布式系统的简单示例似乎并不那么简单,如下所示:

图 3、分布式系统示例,这些应用和服务之间有一些共有的重复的功能

的所有应用和服务包括所有非功能性代码。这种设计有许多缺点。

在这些应用程序和服务中,相同的功能被重复实现,这导致更长的应用程序开发周期(上市时间)和维护成本的指数级增长。

这些通用功能嵌入在每个应用程序中。

和服务中,每个功能都使用了特有的技术和框架,如分别使用 Spring Cloud Gateway 和 Zipkin 或 Jaeger 实现路由和跟踪。底层技术的任何升级都需要修改应用程序,重新构建和部署,导致停机和中断。

由于存在这些挑战,分布式系统变得复杂。这些应用程序需要重新设计和重构,以避免筒仓式开发和一次性解决方案的泛滥。

由于网络越来越稳定和可靠,可以开始将“进程内”调用(如图 3 所示)转换为“通过网络”通信了。

经过重新设计后,借助“公共服务”这一设计模式,这些复杂的系统可以使用共有的功能,但又不必将它们嵌入到每个应用程序和服务中。

公共服务

对于嵌入在每个应用程序里的代码,我们的处理方式是将每个公共功能封装到自己的服务里,并托管在云中一个中央服务器(也许是 VM)上或容器中。

图 4、封装在独立微服务中的公共功能

当应用需要执行公共功能时,客户端应用程序就会调用这些远程服务。如图 4 所示,公共逻辑不再嵌入到每个应用程序或业务服务中。

公共服务应该是无状态的,最好是按照 12 要素应用最佳实践开发或重构,这样就可以在消费者应用程序中重用,提升其价值。

我们可以使用开源框架来开发这些公共服务,如用于 Java 应用程序的 Spring Boot 和 Spring Cloud,用于 ASP.NET 应用程序的 Asp.Net Core中间件。在理想情况下,这些服务都是 12 要素应用程序,都可以比较容易地部署到任何云平台上。在生产环境中管理和监控也比较容易。

这种架构有若干优点:

开发速度更快,交付时间更短,这也意味着上市时间更短。

单个部署,独立于其他应用程序和服务,因此,组件之间的依赖性较小。

可以对每个服务进行扩展。

天然符合安全和技术标准。

更小、更快、更简单的在线维护让我们不必在升级共享功能时重新构建和部署所有应用程序和服务。

长期来看,技术债务更少。

这些公共服务可以托管在云平台上(如 AWS、Azure、Kubernetes 或 VMWare Tanzu Application Service,之前叫 Pivotal Cloud Foundry)。这些平台对自动扩展、监控、快捷部署等特性提供了良好的支持。

然而,公共服务只是云原生之旅的过渡架构,并非最终目标。即便如此,基于公共服务的架构也带来了不少好处,当然也带来了一些挑战,包括紧耦合的服务交互,以及在路由、发现、断路器策略方面缺少中心化的策略执行机制。

关于那些新出现的挑战,本文稍后会专门介绍。

随着微服务在组织里的采用和推广,客户端应用程序和业务服务以及服务与服务之间的通信变得非常重要。如果处理不好这种通信复杂性,可能会导致服务性能退化以及系统可用性问题。

现在,让我们更详细地看下应用和服务之间的通信挑战。

2

挑战 2:应用与服务以及服务与服务之间的通信

随着我们将大型应用程序分解成细粒度的服务,部署的组件总量在增加,这使得这些组件之间的交互变得越来越复杂。图 5 说明了这种复杂性。

图 5、应用程序与服务之间通信的挑战

即使是对于从每个客户端应用程序中提取出来单独部署的公共功能,服务之间的相互依赖以及服务之间的调用方式对于这种架构也是一个很大的威胁。

让我们扩展下前面的例子,增加一些业务服务,看看对服务通信有什么影响。

从图 5 服务之间的通信可以看出,不同的服务之间仍然是紧耦合的,当整个系统变慢或是出现中断时,还是很难准确定位哪个服务有问题。

我们可能会想,其他采用微服务的公司同样也会面临交互模型复杂这样的挑战。他们确实遇到了。像 Netflix、Amazon、Twitter 这些公司都经历过同样的挑战,原因是任何应用程序或服务调用其他的服务时缺少一个有效的服务通信模型或治理流程。正如本系列文章第二部分 指出的那样,这种架构挑战在行业里相当普遍,它被定义成一个反模式“死星架构“。

这些公司是通过服务编排来克服这一架构挑战的。

3

服务编排

图 6、利用服务编排改进服务间通信

在图 6 所示的服务编排模型中,我们对于公共服务的处理还是像之前的架构一样,在客户端应用程序之外,它们会单独部署,有自己的生命周期和扩展性要求。

最主要的改进是,我们将路由服务移到了所有公共服务的前面。

客户端应用程序应该只调用路由服务。路由服务将根据用例以及来自客户端应用程序的请求的上下文信息,按照预定义的顺序调用一个或多个公共服务和应用服务。

该架构有许多好处:

首先,客户端应用程序和公共服务之间是松耦合的,可提供灵活的流量管理和中心化的策略执行机制。

这些策略可以是安全相关的,如身份验证和授权,可以是 SLA 相关的,如服务重试和断路器规则,还可以是可观测性和监控相关的。

该架构提供系统的端到端监控。

该架构还为其中不同部分(客户端应用程序、后端公共服务或者是路由器本身)的交互提供了很大的灵活性:

客户端应用程序可以是 Web 应用程序、移动 App、IoT 设备或其他服务。

后端服务可以是单体应用、微服务或无服务器函数。

路由服务可以用于提供不同的能力,如路由 / 分流、生产应用零停机的金丝雀部署。

客户端和服务之间的通信可以使用基于请求 / 响应机制的事务性同步方式,也可以使用基于消息发布 / 订阅的异步方式。

在服务编排架构中,消费者应用程序团队只需要关注用户界面和应用程序特有的服务,保护业务逻辑和 IP 不受技术变化和公共基础能力(非应用程序特有的能力)的影响。所有的公共服务――不管是业务服务,非功能性服务,还是平台服务――都托管在云平台上供路由服务调用,路由服务充当了服务编排器的角色。

如图 7 所示,公共服务中使用的所有技术和框架完全是从消费者应用程序中抽象出来的。

4

技术抽象

图 7、基于服务编排的解决方案从客户端应用程序中抽象出来的技术

我们来看下服务编排如何从客户端应用程序中把技术抽象出来。

使用图 7 所示的中心化服务编排器,客户端应用程序不需要知道这些技术中的任何一项。此外,这些技术中的任何一项升级都不会影响客户端应用。

与本文迄今为止所讨论的基于服务的架构类似,虽然服务编排架构看上去同样不错,但它也面临着一些挑战:

路由服务会成为一个单点故障。

会有一些性能开销,因为路由服务需要通过网络调用场景中涉及的每个服务。

没有服务的本地调用。

没有去中心化的策略执行机制。

截至目前,我们前面讨论的 3 种不同的架构(传统的分布式系统、基于微服务的架构和基于服务编排的应用程序)都面临一些挑战。现在,让我们探讨下两种新兴的云原生设计模式:服务网格和挎斗(sidecar)。

5

服务网格和挎斗

在本文最后,我们将探讨基于服务网格和挎斗设计模式的架构模型。Kubernetes 对挎斗模式提供了开箱即用的支持,所以这个模型很适合 Kubernetes 平台。

该架构模型如图 8 所示,和基于服务编排的解决方案一样,其中仍有一个名为“控制平面”的中心化组件,定义和管理不同的策略。

挎斗容器(数据平面的一部分)会在运行时自动注入业务服务。这些挎斗代理会执行在控制平面中定义的策略,并将其复制到数据平面。

基于服务网格的解决方案有助于改善分布式系统架构的安全性、可观测性和流量管理功能。

基于服务网格的解决方案所遵循的基本原则是:集中式的策略管理,非集中式的策略执行(两全其美)。

图 8、面向 Kubernetes 托管应用的服务网格和挎斗

6

服务网格功能

如下所示,与传统的微服务架构相比,基于服务网格的解决方案在连接性、可靠性、安全性和可观测性方面提供了诸多好处。

连接性:

流量控制(路由、分流)

网关(入口、出口)

服务发现

A/B 测试、金丝雀

服务超时、重试

可靠性:

断路器

故障注入 / 混沌测试

安全性:

服务间身份验证(mTLS)

证书管理

用户身份验证(JSON Web Tokens)

用户授权(基于角色的访问控制)

数据加密

可观测性:

监控

遥测、仪表盘、指标

分布式跟踪

服务图

近年来,服务网格技术吸引了许多人的注意,已经有一些实现,如 Istio、Linkerd、Consul Connect 等。由于本文的重点是探讨成功的微服务架构所采用的架构模式,所以我们没有深入探讨服务网格的特性和实现。

1.本站部分来源于互联网用户自主整合上传,如有侵权,请联系我们删除;

2.文章内容并不代表本站的观点或立场,如有关于文章内容,版权或其它问题请联系删除;

3.本文地址:https://jiatu888.com/wlyx/84231.html

最新文章

网站介绍

本站部分内容收集于互联网,如有侵犯贵司(个人)版权,请联系本站删除。

Copyright@2018-2021 www.jiatu888.com 嘉图网 All Rights Reserved 粤ICP备20051635号 网站地图 tag列表

嘉图网