微服务架构中10个常用的设计模式_第1页
微服务架构中10个常用的设计模式_第2页
微服务架构中10个常用的设计模式_第3页
微服务架构中10个常用的设计模式_第4页
微服务架构中10个常用的设计模式_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

微服务架构中10个常用的设计模式从软件开发早期(1960年代)开始,应对大型软件系统中的复杂性一直是一项令人生畏的任务。多年来为了应对软件系统的复杂性,软件工程师和架构师们做了许多尝试:DavidParnas的模块化和封装(1972),EdsgerW.Dijkstra(1974)的关注点分离以及SOA(1988)。他们都是使用分而治之这项成熟的传统技术来应对大型系统的复杂性。自2010年开始,这些技术被证实无法继续应对Web级应用或者现代大型企业级应用的复杂性。因此架构师和工程师们发展出了一种全新的现代方式来解决这个问题,就是微服务架构。它虽然延续了分而治之的思想,但却是以全新的方式来实现的。软件设计模式是解决软件设计中常见问题的通用、可复用的解决方案。设计模式让我们可以分享通用词汇并使用经实战检验的方案,以免重复造轮子。我先简单介绍下微服务架构。通过阅读这篇文章,你会学到:微服务架构微服务架构的优势微服务架构的劣势何时使用微服务架构最重要的微服务架构设计模式,包括其优缺点、用例、上下文、技术栈示例及可用资源。请注意,本清单中的大部分设计模式常出现在多种语境中,并且可以在非微服务架构中使用。而我将在微服务这个特定语境中介绍它们。1微服务架构我在之前的博客《微服务架构概述及为什么要应用在下个项目》和《单体软件架构真的终结了吗?》中对微服务架构有非常详尽的介绍。如果你感兴趣,可以阅读这两篇博客来深入了解。/microservice-architecture-a-brief-overview-and-why-you-should-use-it-in-your-next-project-a17b6e19adfd/looking-beyond-the-hype-is-modular-monolithic-software-architecture-really-dead-e386191610f8那到底什么是微服务架构?有很多种定义方法。我的定义是这这样的:微服务架构指的是将大型复杂系统按功能或者业务需求垂直切分成更小的子系统,这些子系统以独立部署的子进程存在,它们之间通过轻量级的、跨语言的同步(比如REST,gRPC)或者异步(消息)网络调用进行通信。下面是基于微服务架构的商业Web应用的组件视图:来自MdKamaruzzaman的微服务架构

微服务架构的重要特征整个应用程序被拆分成相互独立但包含多个内部模块的子进程与模块化的单体应用(ModularMonoliths)或SOA相反,微服务应用程序根据业务范围或领域垂直拆分。微服务边界是外部的,微服务之间通过网络调用(RPC或消息)相互通信。微服务是独立的进程,它们可以独立部署。它们以轻量级的方式进行通信,不需要任何智能通信通道。

微服务架构的优点更好的开发规模更快的开发速度支持迭代开发或现代化增量开发充分利用现代软件开发生态系统的优势(云、容器、DevOps、Serverless)支持水平缩放和细粒度缩放小体量,较低了开发人员的认知复杂性

微服务架构的缺点更高数量级的活动组件(服务、数据库、进程、容器、框架)复杂性从代码转移到基础设施RPC调用和网络通信的大量增加整个系统的安全性管理更具有挑战性整个系统的设计变得更加困难引入了分布式系统的复杂性

何时使用微服务架构大规模Web应用开发跨团队企业级应用协作开发长期收益优先于短期收益团队拥有能够设计微服务架构的软件架构师或高级工程师2微服务架构的设计模式

独享数据库(DatabaseperMicroservice)当一家公司将大型单体系统替换成一组微服务,首先要面临的最重要决策是关于数据库。单体架构会使用大型中央数据库。即使转移到微服务架构许多架构师仍倾向于保持数据库不变。虽然有一些短期收益,但它却是反模式的,特别是在大规模系统中,微服务将在数据库层严重耦合,整个迁移到微服务的目标都将面临失败(例如,团队授权、独立开发等问题)。更好的方法是为每个微服务提供自己的数据存储,这样服务之间在数据库层就不存在强耦合。这里我使用数据库这一术语来表示逻辑上的数据隔离,也就是说微服务可以共享物理数据库,但应该使用分开的数据结构、集合或者表,这还将有助于确保微服务是按照领域驱动设计的方法正确拆分的。MdKamaruzzaman的微服务独享数据库优点数据由服务完全所有服务的开发团队之间耦合度降低缺点服务间的数据共享变得更有挑战性在应用范围的保证ACID事务变得困难许多细心设计如何拆分单体数据库是一项极具挑战的任务何时使用独享数据库在大型企业应用程序中当团队需要完全把控微服务以实现开发规模扩展和速度提升何时不宜使用独享数据库在小规模应用中如果是单个团队开发所有微服务可用技术示例所有SQL、NoSQL数据库都提供数据的逻辑分离(例如,单独的表、集合、结构、数据库)。

事件源(EventSourcing)在微服务架构中,特别使用独享数据库时,微服务之间需要进行数据交换。对于弹性高可伸缩的和可容错的系统,它们应该通过交换事件进行异步通信。在这种情况,您可能希望进行类似更新数据库并发送消息这样的原子操作,如果在大数据量的分布式场景使用关系数据库,您将无法使用两阶段锁协议(2PL),因为它无法伸缩。而NoSQL数据库因为大多不支持两阶段锁协议甚至无法实现分布式事务。在这些场景,可以基于事件的架构使用事件源模式。在传统数据库中,直接存储的是业务实体的当前“状态”,而在事件源中任何“状态”更新事件或其他重要事件都会被存储起来,而不是直接存储实体本身。这意味着业务实体的所有更改将被保存为一系列不可变的事件。因为数据是作为一系列事件存储的,而非直接更新存储,所以各项服务可以通过重放事件存储中的事件来计算出所需的数据状态。MdKamaruzzaman的事件源优点为高可伸缩系统提供原子性操作自动记录实体变更历史,包括时序回溯功能松耦合和事件驱动的微服务缺点从事件存储中读取实体成为新的挑战,通常需要额外的数据存储(CQRS模式)。系统整体复杂性增加了,通常需要领域驱动设计。系统需要处理事件重复(幂等)或丢失变更事件结构成为新的挑战。何时使用事件源使用关系数据库的、高可伸缩的事务型系统使用NoSQL数据库的事务型系统弹性高可伸缩微服务架构典型的消息驱动或事件驱动系统(电子商务、预订和预约系统)何时不宜使用事件源使用SQL数据库的低可伸缩性事务型系统在服务可以同步交换数据(例如,通过API)的简单微服务架构中。可用技术示例事件存储:EventStoreDB、ApacheKafka、ConfluentCloud、AWSKinesis、AzureEventHub、GCPPub/Sub、AzureCosmosDB、MongoDB、Cassandra、AmazonDynamoDB框架:Lagom、Akka、Spring、akkatecture、Axon、Eventuate

命令和查询职责分离(CQRS)如果我们使用事件源,那么从事件存储中读取数据就变得困难了。要从数据存储中获取实体,我们需要处理所有的实体事件。有时我们对读写操作还会有不同的一致性和吞吐量要求。这种情况,我们可以使用CQRS模式。在该模式中,系统的数据修改部分(命令)与数据读取部分(查询)是分离的。而CQRS模式有两种容易令人混淆的模式,分别是简单的和高级的。在其简单形式中,不同实体或ORM模型被用于读写操作,如下所示:MdKamaruzzaman的CQRS(简单)它有助于强化单一职责原则和分离关注点,从而实现更简洁的设计。搜索公众号顶级架构师后台回复“offer”,获取一份惊喜礼包。在其高级形式中,会有不同的数据存储用于读写操作。高级的CQRS通常结合事件源模式。根据不同情况,会使用不同类型的写数据存储和读数据存储。写数据存储是“记录的系统”,也就是整个系统的核心源头。MdKamaruzzaman的CQRS(高级)对于读频繁的应用程序或微服务架构,OLTP数据库(任何提供ACID事务保证的关系或非关系数据库)或分布式消息系统都可以被用作写存储。对于写频繁的应用程序(写操作高可伸缩性和大吞吐量),需要使用写可水平伸缩的数据库(如全球托管的公共云数据库)。标准化的数据则保存在写数据存储中。对搜索(例如ApacheSolr、Elasticsearch)或读操作(KV数据库、文档数据库)进行优化的非关系数据库常被用作读存储。许多情况会在需要SQL查询的地方使用读可伸缩的关系数据库。非标准化和特殊优化过的数据则保存在读存储中。数据是从写存储异步复制到读存储中的,所以读存储和写存储之间会有延迟,但最终是一致的。优点在事件驱动的微服务中数据读取速度更快数据的高可用性读写系统可独立扩展缺点读数据存储是弱一致性的(最终一致性)整个系统的复杂性增加了,混乱的CQRS会显着危害整个项目。何时使用CQRS在高可扩展的微服务架构中使用事件源在复杂领域模型中,读操作需要同时查询多个数据存储。在读写操作负载差异明显的系统中何时不宜使用CQRS在没有必要存储大量事件的微服务架构中,用事件存储快照来计算实体状态是一个更好的选择。在读写操作负载相近的系统中。可用技术示例写存储:EventStoreDB,ApacheKafka,ConfluentCloud,AWSKinesis,AzureEventHub,GCPPub/Sub,AzureCosmosDB,MongoDB,Cassandra.AmazonDynamoDB读存储:ElasticSearch,Solr,CloudSpanner,AmazonAurora,AzureCosmosDB,Neo4j框架:Lagom,Akka,Spring,akkatecture,Axon,Eventuate

Saga如果微服务使用独享数据库,那么通过分布式事务管理一致性是一个巨大的挑战。你无法使用传统的两阶段提交协议,因为它要么不可伸缩(关系数据库),要么不被支持(多数非关系数据库)。但您还是可以在微服务架构中使用Saga模式实现分布式事务。Saga是1987年开发的一种古老模式,是关系数据库中关于大事务的一个替代概念。但这种模式的一种现代变种对分布式事务也非常有效。Saga模式是一个本地事务序列,其每个事务在一个单独的微服务内更新数据存储并发布一个事件或消息。Saga中的首个事务是由外部请求(事件或动作)初始化的,一旦本地事务完成(数据已保存在数据存储且消息或事件已发布),那么发布的消息或事件则会触发Saga中的下一个本地事务。MdKamaruzzaman的Saga如果本地事务失败,Saga将执行一系列补偿事务来回滚前面本地事务的更改。Saga事务协调管理主要有两种形式:事件编排Choreography:分散协调,每个微服务生产并监听其他微服务的事件或消息然后决定是否执行某个动作。命令编排Orchestration:集中协调,由一个协调器告诉参与的微服务哪个本地事务需要执行。优点为高可伸缩或松耦合的、事件驱动的微服务架构提供一致性事务。为使用了不支持2PC的非关系数据库的微服务架构提供一致性事务。缺点需要处理瞬时故障,并且提供等幂性。难以调试,而且复杂性随着微服务数量增加而增加。何时使用Saga在使用了事件源的高可伸缩、松耦合的微服务中。在使用了分布式非关系数据库的系统中。何时不宜使用Saga使用关系数据库的低可伸缩性事务型系统。在服务间存在循环依赖的系统中。可用技术示例Axon,Eventuate,Narayana

面向前端的后端(BFF)在现代商业应用开发,特别是微服务架构中,前后端应用是分离和独立的服务,它们通过API或GraphQL连接。如果应用程序还有移动App客户端,那么Web端和移动客户端使用相同的后端微服务就会出现问题。因为移动客户端和Web客户端有不同的屏幕尺寸、显示屏、性能、能耗和网络带宽,它们的API需求不同。面向前端的后端模式适用于需要为特殊UI定制单独后端的场景。它还提供了其他优势,比如作为下游微服务的封装,从而减少UI和下游微服务之间的频繁通信。此外,在高安全要求的场景中,BFF为部署在DMZ网络中的下游微服务提供了更高的安全性。MdKamaruzzaman的面向前端的后端优点分离BFF之间的关注点,使得我们可以为具体的UI优化他们。提供更高的安全性减少UI和下游微服务之间频繁的通信缺点BFF之间代码重复大量的BFF用于其他用户界面(例如,智能电视,Web,移动端,PC桌面版)需要仔细的设计和实现,BFF不应该包含任何业务逻辑,而应只包含特定客户端逻辑和行为。何时使用BFF如果应用程序有多个含不同API需求的UI出于安全需要,UI和下游微服务之间需要额外的层。如果在UI开发中使用微前端。何时不宜使用BFF如果应用程序虽有多个UI,但使用的API相同。如果核心微服务不是部署在DMZ网络中。可用技术示例任何后端框架(Node.js,Spring,Django,Laravel,Flask,Play,…)都能支持。

API网关在微服务架构中,UI通常连接多个微服务。如果微服务是细粒度的(FaaS),那么客户端可能需要连接非常多的微服务,这将变得繁杂和具有挑战性。此外,这些服务包括它们的API还将不断进化。大型企业还希望能有其他横切关注点(SSL终止、身份验证、授权、节流、日志记录等)。一个解决这些问题的可行方法是使用API网关。API网关位于客户端APP和后端微服务之间充当facade,它可以是反向代理,将客户端请求路由到适当的后端微服务。它还支持将客户端请求扇出到多个微服务,然后将响应聚合后返回给客户端。它还支持必要的横切关注点。MdKamaruzzaman的API网关优点在前端和后端服务之间提供松耦合减少客户端和微服务之间的调用次数通过SSL终端、身份验证和授权实现高安全性集中管理的横切关注点,例如,日志记录和监视、节流、负载平衡。缺点可能导致微服务架构中的单点故障额外的网络调用带来的延迟增加如果不进行扩展,它们很容易成为整个企业应用的瓶颈。额外的维护和开发费用何时使用API网关在复杂的微服务架构中,它几乎是必须的。在大型企业中,API网关是中心化安全性和横切关注点的必要工具。何时不宜使用API网关在安全和集中管理不是最优先要素的私人项目或小公司中。如果微服务的数量相当少。可用技术示例AmazonAPI网关,AzureAPI管理,Apigee,Kong,WSO2API管理器

Strangler如果想在运行中的项目中使用微服务架构,我们需要将遗留的或现有的单体应用迁移到微服务。将现有的大型在线单体应用程序迁移到微服务是相当有挑战性的,因为这可能破坏应用程序的可用性。一个解决方案是使用Strangler模式。Strangler模式意味着通过使用新的微服务逐步替换特定功能,将单体应用程序增量地迁移到微服务架构。此外,新功能只在微服务中添加,而不再添加到遗留的单体应用中。然后配置一个Facade(API网关)来路由遗留单体应用和微服务间的请求。当某个功能从单体应用迁移到微服务,Facade就会拦截客户端请求并路由到新的微服务。一旦迁移了所有的功能,遗留单体应用程序就会被“扼杀(Strangler)”,即退役。搜索公众号后端架构师后台回复“架构整洁”,获取一份惊喜礼包。MdKamaruzzaman的Strangler优点安全的迁移单体应用程序到微服务可以并行地迁移已有功能和开发新功能迁移过程可以更好把控节奏缺点在现有的单体应用服务和新的微服务之间共享数据存储变得具有挑战性添加Facade(API网关)将增加系统延迟端到端测试变得困难何时使用Strangler将大型后端单体应用程序的增量迁移到微服务何时不宜使用Strangler如果后端单体应用很小,那么全量替换会更好。如果无法拦截客户端对遗留的单体应用程序的请求。可用技术示例API网关后端应用框架。

断路器在微服务架构中,微服务通过同步调用其他服务来满足业务需求。服务调用会由于瞬时故障(网络连接缓慢、超时或暂时不可用)导致失败,这种情况重试可以解决问题。然而,如果出现了严重问题(微服务完全失败),那么微服务将长时间不可用,这时重试没有意义且浪费宝贵的资源(线程被阻塞,CPU周期被浪费)。此外,一个服务的故障还会引发整个应用系统的级联故障。这时快速失败是一种更好的方法。在这种情况,可以使用断路器模式挽救。一个微服务通过代理请求另一个微服务,其工作原理类似于电气断路器,代理通过统计最近发生的故障数量,并使用它来决定是继续请求还是简单的直接返回异常。MdKamaruzzaman的断路器断路器可以有以下三种状态:关闭:断路器将请求路由到微服务,并统计给定时段内的故障数量,如果超过阈值,它就会触发并进入打开状态。打开:来自微服务的请求会快速失败并返回异常。在超时后,断路器进入半开启状态。半开:只有有限数量的微服务请求被允许通过并进行调用。如果这些请求成功,断路器将进入闭合状态。如果任何请求失败,断路器则会进入开启状态。优点提高微服务架构的容错性和弹性阻止引发其他微服务的级联故障缺点需要复杂的异常处理日志和监控应该支持人工复位何时使用断路器在微服务间使用同步通信的紧耦合的微服务架构中如果微服务依赖多个其他微服务何时不宜使用断路器松耦合、事件驱动的微服务架构如果微服务不依赖于其他微服务可用技术示例API网关,服务网格,各种断路器库(Hystrix,Reselience4J,Polly)。

外部化配置每个业务应用都有许多用于各种基础设施的配置参数(例如,数据库、网络、连接的服务地址、凭据、证书路径)。此外在企业应用程序通常部署在各种运行环境(Local、Dev、Prod)中,实现这些的一个方法是通过内部配置。这是一个致命糟糕实践,它会导致严重的安全风险,因为生产凭证很容易遭到破坏。此外,配置参数的任何更改都需要重新构建应用程序,这在在微服务架构中会更加严峻,因为我们可能拥有数百个服务。更好的方法是将所有配置外部化,使得构建过程与运行环境分离,生产的配置文件只在运行时或通过环境变量使用,从而最小化了安全风险。优点生产配置不属于代码库,因而最小化了安全漏洞。修改配置参数不需要重新构建应用程序。缺点我们需要选择一个支持外部化配置的框架。何时使用外部化配置任何重要的生产应用程序都必须使用外部化配置。何时不宜使用外部化配置在验证概念的开发中。可用技术示例几乎所有企业级的现代框架都支持外部化配置。

消费端驱动的契约测试在微服务架构中,通常有许多有不同团队开发的微服务。这些微型服务协同工作来满足业务需求(例如,客户请求),并相互进行同步或异步通信。消费端微服务的集成测试具有挑战性,通常用TestDouble以获得更快、更低成本的测试运行。但是TestDouble通常并不能代表真正的微服务提供者,而且如果微服务提供者更改了它的API或消息,那么TestDouble将无法确认这些。另一种选择是进行端到端测试,尽管它在生产之前是强制性的,但却是脆弱的、缓慢的、昂贵的且不能替代集成测试(TestPyramid)。在这方面消费端驱动的契约测试可以帮助我们。在这里,负责消费端微服务的团队针对特定的服务端微服务,编写一套包含了其请求和预期响应(同步)或消息(异步)的测试套件,这些测试

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论