1.3 对高可靠性平台和基础设施的需求
前文讨论了云支持和云原生应用程序以及它们如何托管在底层云基础架构上以完成服务交付。应用程序的功能非常强大。但是,非功能性要求,例如应用程序的可伸缩性、可用性、安全性、可靠性、性能/吞吐量、可修改性等,正在被广泛使用。也就是说,开发高质量的应用程序对IT专业人员来说是一个真正的挑战。要将各种NFR纳入到云应用程序中,可使用多种设计、开发、测试、部署技术、技巧和模式。有一些最佳做法和关键准则可以用于开发高扩展、高可用、高可靠的应用程序。
另一个挑战是建立和维持高能力、高认知的云基础架构,以展现可靠的行为。高弹性、强大且通用的应用程序和基础架构的组合可实现高度可靠的IT,以满足业务的生产力、经济性和适应性等需求。
在了解了战术和战略意义及价值之后,企业开始有意识地接受开创性的云范式。也就是说,各种传统IT环境正在逐步支持云,以获得宣称的业务、技术和使用优势。但是,仅云计算并不能解决每个业务和IT问题。除了建立针对特定目的和不可知的云中心,云基础架构还有很多事情要做,才能实现业务敏捷性和可靠性。云中心运营流程需要改进、集成和编排以达到优化组织流程的目的。每个云中心的运营都需要精确定义和自动化,以实现IT敏捷性的真正含义。借助于灵活可靠的云应用程序和环境,应用程序业务能力和价值必将显著提升。
1.3.1 对可靠软件的需求
我们知道,软件可靠性对于数字时代软件工程的持续成功至关重要。但是,这实现起来并不容易。由于软件套件的复杂性不断提高,确保软件的高可靠性变得非常困难且耗时。业内相关人员已经提出了一些有趣和鼓舞人心的想法来实现可靠的软件。主要有下面两种方法。
-
弹性微服务可以实现可靠的软件应用程序。常见的技术包括微服务、容器、Kubernetes、Terraform、API网关和管理套件、Istio、Spinnaker。
-
响应性系统(弹性、响应性、消息驱动和可恢复)。它以著名的响应式宣言(Reactive Manifesto)为基础。有一些特定的语言和平台(如RxJava、play框架等)可用于开发响应式系统。vAkka是一个用于为Java和Scala构建高并发、分布式和弹性的消息驱动应用程序的工具包。
在开发可靠的软件包时,还需要考虑下面这些因素。
-
通过各种测试方法来验证和确认软件的可靠性。
-
软件可靠性预测算法和方法。
-
静态和动态代码分析方法。
-
用于构建可靠软件包的模式、流程、平台和实践。
下面详细讨论这些。
1.微服务架构的出现
任务关键型应用程序和通用应用程序将使用广受欢迎的MSA模式来开发。开发人员正在使用MSA范式有意识地废除单体应用程序,而且这对用户和程序开发人员来说非常正确且紧密相关。微服务是用于开发下一代应用程序的新构建块,它是一种易于管理、可独立部署、可水平扩展,而且相对简单的服务。微服务具有可被公开发现、可网络访问、可互操作、由API驱动、可组合、可替换以及高度隔离等特性。以下是MSA的一些优点。
-
可伸缩性
:任何生产级应用程序通常都可以使用三种类型的伸缩。第一种是
x
轴缩放,用于水平可伸缩性。也就是说,应用程序必须是可以克隆的,以保证高可用性。第二种类型是
y
轴缩放。这是为了将应用程序分成各种应用程序的功能。借助于微服务架构,应用程序(传统应用程序、单体应用程序和大规模应用程序)被划分为易于管理的微服务的集合。每个微服务履行一项责任。第三种是
z
轴缩放,用于对数据进行分区或分片。数据库在构建动态应用程序中起着至关重要的作用。随着NoSQL数据库的使用,共享的概念变得更加突出。
-
可用性
:多个微服务实例部署在不同的容器(Docker)中,以确保高可用性。这种冗余确保了服务和应用程序的可用性。由于多个服务实例是通过容器进行托管和运行的,因此服务实例的负载均衡可以确保服务的高可用性。广泛使用的断路器模式用于实现亟需的容错能力。也就是说,通过实例实现的服务冗余确保了高可用性,而断路器模式则保证了服务的弹性。服务注册、发现和配置功能将引领新服务的开发和发现,从而带来额外的业务(垂直)和IT(水平)服务。随着服务形成了一个动态的、临时的服务网络,服务通信、协作、佐证和关联的日子就不遥远了。
-
持续部署
:微服务可独立部署、水平扩展和自定义。微服务是解耦/轻耦合和内聚的,从而实现了模块化。应用程序通过采用这种架构风格,不再出现强依赖性的问题,这也促使相互独立的服务能够更快和更持续地进行部署。
-
松耦合
:如前所述,微服务天生具备松耦合特性,因此具有了自治性和独立性。每个微服务在服务级别都有自己的分层架构,在后端有自己的数据库。
-
多语言微服务
:微服务可以通过多种编程语言实现,因此不存在技术锁定的情况,任何技术都可用于实现微服务。同样,微服务没有强制使用某些数据库。微服务可与任何文件系统SQL数据库、NoSQL数据库和NewSQL数据库、搜索引擎等配合使用。
-
性能
:在微服务领域有相应的性能工程和增强技术。例如,高阻塞调用服务是在单线程技术栈中实现的,而针对高CPU使用率的服务则使用多个线程来实现。
采用快速、成熟和稳定的微服务架构,对业务和IT团队还有其他好处。工具生态系统正在崛起,因此微服务的实现和参与也得以简化。自动化工具可以简化并加快微服务的构建和运营。
2.Docker支持的容器化
Docker的理念震撼了软件世界。Docker通过容器化实现了一系列进步。软件可移植性的要求长期以来一直存在,现在可以通过开源的Docker平台得以解决。托管了各种微服务的Docker的实时弹性使得业务关键型软件应用程序的实时可扩展性成为容器化迅速普及的关键因素和原因。微服务和Docker的交叉为软件开发人员以及系统管理员带来了范式转换。Docker的轻量级特性以及与Docker平台相关的标准化打包格式在稳定和加速软件部署方面发挥了很大作用。
容器是一种打包软件的方法,它可以在任何操作环境中启用软件所需的配置文件、依赖项和二进制文件。容器有如下重要的优点。
-
环境一致性
:在容器中运行的应用程序/进程/微服务在不同的环境(开发、测试、复制和生产)中表现一致。这消除了环境的不一致性,并减少了测试和调试的麻烦,减少了耗时。
-
快速的部署
:容器是轻量级的,可以在几秒钟内启动和停止,因为它不需要启动任何操作系统镜像。这最终有助于实现更快的创建、部署速度和高可用性。
-
隔离
:使用相同资源在同一台计算机上运行的容器彼此隔离。当使用docker run命令启动容器时,Docker平台在幕后做了一些有趣的事情。也就是说,Docker为容器创建了一组命名空间和控制组(cgroup)。命名空间和控制组是内核级功能。命名空间将最近创建的容器与主机中运行的其他容器相互资源隔离。此外,容器与Docker所在的主机明显隔离。这种隔离对安全有很大的好处。这种独特的隔离可确保一个容器上的任何恶意软件、病毒或任何网络钓鱼攻击不会传播到其他正在运行的容器中。简而言之,在容器中运行的进程无法查看和影响在另一个容器或主机系统中运行的进程。此外,随着向多容器应用程序时代的发展,每个容器都必须拥有自己的网络栈,用于容器互连和通信。通过这种隔离,容器不会获得对同一Docker主机中或跨该主机的其他容器的套接字或接口的任何特权访问。通过网络接口进行交互是容器彼此交互以及与主机交互的唯一方式。此外,当我们为容器指定公共端口时,容器之间仅允许特定IP的流量进来。它们可以相互ping通、发送和接收UDP数据包,以及建立TCP连接。
-
可移植性
:容器可以在任何地方运行。它们可以在笔记本电脑、企业服务器和云服务器中运行。也就是说,通过容器化可以实现一次性写入并在任何地方运行的长期目标。
容器还有其他重要的优点。有些产品和平台可以促进容器化和虚拟化的快速融合,以满足新兴的IT需求。
3.容器化的微服务
最近IT领域的一个范式转变是出现了用于灵活托管和运行微服务的容器。由于容器的轻型特性,因此配置容器可以用闪电般的速度完成。此外,微服务的水平可伸缩性可通过其托管环境(容器)轻松实现。因此,微服务和容器的组合为软件开发和IT操作带来了许多好处。单个物理机器中可以有数百个容器。
著名的链接(linkage)有助于在一台机器中拥有多个微服务实例。通过Docker主机上容器之间的相互通信,多个微服务实例可以找到彼此,以组成更大、更好的业务和流程感知的组合服务。因此,容器化空间的所有进步都对微服务工程、管理、治理、安全、编排和科学产生了直接和间接的影响。
容器化云环境的关键技术驱动因素如下。
-
容器(应用程序和数据)的成熟度和稳定性。
-
新型容器(如Kata容器和Hyper容器)的出现。
-
MSA正在成为企业级应用程序最优化的架构风格。
-
容器和微服务之间有很酷的融合。在容器中执行托管和运行微服务是最优化的实现。
-
Web/云、移动、可穿戴和物联网应用程序、平台、中间件、UI、操作、分析和交易应用程序被现代化为支持云的应用程序,以及新建应用程序被构建为云原生应用程序。
-
Kubernetes作为容器集群、编排和管理平台解决方案的迅速普及导致了容器化云的实现。
-
API网关的出现简化了微服务的访问和使用流程。
-
服务网格解决方案更高的成熟度和稳定性保证了微服务的弹性和云托管应用程序的可靠性。
容器化云环境的挑战如下。
-
从单体应用程序转向微服务并非易事。
-
云环境中可能存在数千个微服务及其实例(冗余)。
-
在开发应用程序时,应用程序的数据流和控制流应该在多个云中心上不同的分布式微服务之间传输。
-
实践表明,微服务实例和容器之间存在一对一的映射。也就是说,需要为单独的微服务实例分配单独的容器。
-
由于微服务的部署会产生密集的环境,因此容器云的运营和管理复杂性势必提高。
-
在微服务之间跟踪服务请求消息和事件成为一件复杂的事情。
-
在微服务环境中进行故障排除和根本原因分析成为一项艰巨的任务。
-
容器生命周期管理功能必须自动化。
-
客户端到微服务(从北到南的流量)的通信仍然是一个挑战。
-
服务到服务(从东向西的流量)的通信必须具有弹性和健壮性。
4.用于容器编排的Kubernetes
MSA需要创建和聚合几个细粒度且易于管理的服务,这些服务具有轻量级、可独立部署、可水平扩展、容易移植等特点。容器为加速构建、包装、传输、部署和交付微服务提供了理想的托管和运行时环境,此外还提供了其他好处,比如工作负载隔离和自动化生命周期管理。随着更多的容器(微服务及其实例)被置入每台物理机器中,容器化云环境的运营和管理复杂性更高。此外,多容器应用程序的数量正在迅速增加。因此,需要一个标准化的编排平台以及容器集群管理功能。Kubernetes是目前流行的容器集群管理器之一,它由几个架构组件组成,包括Pod、标签、复制控制器和服务。下面来看一下。
-
如前所述,Kubernetes架构中有几个重要的组件。Pod是最明显、最可行、最短暂的单元,它由一个或多个紧密耦合的容器组成。这意味着Pod内的容器要“同生共死”,即不可能对Pod内单独的容器进行监控、测量和管理。换句话说,Pod是Kubernetes的基本操作单元。Kubernetes不在容器级别运行。在单个服务器节点中可以有多个Pod,并且Pod之间可以轻松共享数据。Kubernetes自动为各种服务配置和分配Pod。每个Pod都有自己的IP地址,并共享本地主机和卷。根据故障和失败,Kubernetes可以快速配置和安排额外的Pod,以确保服务的连续性。同时,在负载增加的情况下,Kubernetes以Pod形式添加额外资源,以确保系统和服务性能的稳定。Kubernetes可以根据流量来添加和删除资源,以实现弹性目标。
-
标签通常是附加到对象(包括Pod)的元数据。
-
如前所述,复制控制器可以利用Pod模板创建新的Pod。也就是说,根据配置,Kubernetes能够在任何时间点运行足够数量的Pod。复制控制器通过不断轮询容器集群来满足此独特需求。如果有任何Pod出现故障关闭,复制控制器会立即启动,以包含一个额外的Pod,从而确保指定数量的Pod(带有一组给定的标签)在容器内运行。
-
服务是嵌入到Kubernetes架构中的另一项功能。该功能提供了一种低开销方式,可将各种服务请求路由到一组Pod以完成这些请求。标签用于选择最合适的Pod。服务提供了使用群集将传统组件(例如数据库)外部化的方法。它还提供了稳定的端点,以应对集群的收缩和增长,而且可以在群集管理器内的新节点之间进行配置。这样一来,在跟踪集群实例内存在的应用程序组件时,就轻松多了。
Kubernetes促进了应用程序和数据容器在复合服务开发中的快速扩展,并加快了容器化时代的进展。传统和现代的IT环境都在采用这种划分技术,以克服虚拟化技术的一些关键挑战和问题。
API网关和管理套件
:这是另一个引入可靠客户端和服务交互的平台。API网关的各种特性和功能如下。
-
API网关充当路由器。它是微服务集合的唯一入口点。这样,微服务不再需要公开,而是放在内部网络后面。API网关负责对一个服务或其他服务发出请求(服务发现)。
-
API网关充当数据聚合器。API网关从多个服务中提取数据并将其聚合以返回单个丰富的响应。根据API消费者的不同,数据表示可能会根据需要而变化,而这正是服务于前端的后端(Backend For Frontend,BFF)发挥作用的地方。
-
API网关是一个协议抽象层。无论在内部使用何种协议或技术与微服务进行通信,API网关都可以作为REST API或GraphQL公开。
-
对错误进行集中管理。当服务不可用或速度太慢时,API网关可以提供来自缓存的数据、进行默认响应,或做出明智的决策,以避免产生瓶颈或传播致命错误。这使电路保持闭合(断路器),并使系统更具弹性和可靠性。
-
微服务提供的API粒度通常与客户端所需的不同。微服务通常提供细粒度的API,这意味着客户端需要与多个服务进行交互。API网关可以将多个细粒度的API组合成一个客户端可以使用的API,从而简化客户端应用程序并提高其性能。
-
客户端的类型不同,则网络性能也不相同。API网关可以定义特定于设备的API,以减少通过较慢的广域网(WAN)或移动网络进行的呼叫数量。作为服务器端应用程序的API网关可以更高效地通过LAN对后端服务进行多次调用。
-
服务实例的数量及其位置(主机和端口)动态变化。API网关可以通过确定后端服务的位置来合并这些后端变更,而无须请求前端客户端应用程序。
-
不同的客户端可能需要不同级别的安全性。例如,在访问同一个API时,外部应用程序可能需要更高级别的安全性,而内部应用程序可能无须额外的安全层就可以访问这个API。
用于微服务弹性的服务网络解决方案
:分布式计算是运行Web规模的应用程序和进行大数据分析的发展方向。在面向客户的应用程序中,各种应用模块(微服务)可以进行横向扩展,其生命周期也可以单独进行管理,因此IT资源的分布式部署(可高度编程和可配置的裸机服务器、虚拟机和容器)得到了业内人士的坚持。也就是说,我们必须实现对IT资源和应用程序的分布式部署进行集中管理的目标。这种类型的监控、测量和管理是必需的,可以确保对应各种设备和组件进行主动、及时的故障预测和纠正。换句话说,在分布式计算时代,实现弹性目标非常重要。策略的制定和执行是引入一些特定自动化的可靠方法。有一些特定于编程语言的框架可以将额外的代码和配置添加到应用程序代码中,以实现应用程序的高可用性和容错性。
因此,在微服务领域拥有与编程无关的弹性和容错框架是至关重要的。服务网格是创建和维持弹性微服务的适当方式。Istio是一个业界知名的开源框架,它提供了一种创建服务网格的简便方法。图1.1所示为传统的基于ESB工具、面向服务的应用程序集成与基于轻量级、弹性微服务的应用程序交互之间的区别。
图1.1
服务网格是一种软件解决方案,用于建立从各种参与服务的网格。服务网格软件可以建立和维持服务间的通信。服务网格是一种基础设施解决方案。我们来看下面这些情况。
-
给定的微服务不直接与其他微服务通信。
-
相反,所有服务与服务之间的通信都在服务网格解决方案上进行,这种解决方案是一种边车代理(sidecar proxy)。sidecar是一种著名的软件集成模式。
-
服务网格为一些关键的网络功能(比如微服务的弹性和可发现性)提供了内置支持。
也就是说,核心和公共网络服务正在通过服务网格进行识别、抽象和交付,这可以让服务开发人员专注于业务功能。特定于业务的功能与服务有关,而所有水平的服务(技术、网络通信、安全、中介、路由和过滤)都在服务网格中实现。例如,断路器模式如今在服务代码中得以实现。现在,这种模式正在通过服务网格解决方案来实现。
服务网格适用于多种语言。也就是说,可以使用任何编程和脚本语言对服务进行编码。此外,服务网格还有几种文本和二进制数据传输协议。微服务在与其他微服务交互时,必须先与服务网格交互以启动服务通信。这种服务到服务的网格通信可以发生在所有的标准协议上,例如HTTP1.x/2.x、gRPC等。可以使用任何技术实现编写微服务,而且编写的微服务仍然可以使用服务网格。图1.2所示为服务网格在使微服务具有弹性方面的贡献。
图1.2
最后,将弹性微服务组合起来,就可以生成可靠的应用程序。因此,所有参与的微服务的弹性构成了高度可靠的应用程序。
5.弹性微服务和可靠的应用程序
渐渐地,世界被连接起来,并以软件为基础。我们经常听到、读到和体验到软件定义的计算、存储和网络能力。日常环境中的物理、机械、电气和电子系统都被精心地“塞进”了软件,使其在行动和反应中变得灵巧,有意识,有适应性,有表达力。在产生和维持受数字影响与变革的社会方面,软件注定要发挥重要作用,新一代软件支持系统的一个突出特点是通过一种或多种方式始终保持响应性。也就是说,它们必须得到正确的响应。如果一个系统没有响应,则另一个系统必须正确且快速地响应。换言之,如果系统出现故障,替代系统必须做出响应。
这通常称为系统弹性。如果由于用户和数据负载过重而导致系统压力过大,则必须配置其他系统以响应用户的请求,确保不会出现任何响应变慢和发生故障的情况。也就是说,对于当今的软件系统来说,自动扩展是一个重要的属性,而且与企业和用户相关。为了使系统具有弹性,产生消息驱动系统是关键的决策。消息驱动系统称为响应式系统。我们在这里解释一下系统弹性背后的概念。
可扩展的应用程序可以自动扩展,从而可以持续运行。在某一时刻,可以有更多的用户访问该应用程序。尽管如此,该应用程序必须不断进行交易,并能恰当地处理流量峰值和流量下降。通过仅在需要时添加和删除虚拟机、容器,可扩展应用程序可以执行其被分配的任务,而不会出现任何响应变慢或发生故障的情况。通过动态配置额外资源,可扩展应用程序的利用率是最佳的。可扩展应用程序支持按需计算。可能有许多用户请求应用程序的服务,也可能有更多的数据被推送到应用程序中。容器和虚拟机是应用程序组件的主要资源和运行时环境。
8hmpz6I6H556V+ULTa9IndP3apwALFa1VgnEg6EHcmjr7qxCP68T0HwTDdsjVCrT