微服务架构模式正在迅速成为业界的基础,作为单体应用和面向服务架构的可行替代方案。由于这种体系结构模式仍在不断发展,因此业界对此模式的全部内容及其实现方式存在很多困惑。本报告的这一部分将为您提供理解这一重要架构模式的优势(和权衡)所必需的关键概念和基础知识,以及它是否适合您的应用程序。
模式描述
无论您选择哪种拓扑或实现方式,都有一些适用于通用体系结构模式的常见核心概念。这些概念中的第一个是单独部署单元的概念。如在示出的图4-1中,微服务体系结构的每个组件被部署为单独的单元,从而允许通过有效的和简化的输送管道更容易部署,增强的可伸缩性,和高度的应用程序和组件的应用程序中去耦合。
也许用这种模式理解的最重要的概念是服务组件的概念。不考虑微服务架构中的服务,最好考虑服务组件,这些组件的粒度可以从单个模块到应用程序的大部分变化。服务组件包含一个或多个模块(例如,Java类),其表示单一用途功能(例如,为特定城市或城镇提供天气)或大型商业应用的独立部分(例如,股票交易放置或确定汽车保险费率)。设计适当级别的服务组件粒度是微服务架构中的最大挑战之一。以下service-component orchestration子部分将更详细地讨论此挑战。
图4-1。基本微服务架构模式
微服务架构模式中的另一个关键概念是它是一个分布式架构,这意味着架构中的所有组件都完全脱离,并通过某种远程访问协议(例如,JMS,AMQP,REST,SOAP, RMI等)。此体系结构模式的分布式特性是它如何实现其一些卓越的可伸缩性和部署特性。
微服务架构的一个令人兴奋的事情是它从与其他常见架构模式相关的问题演变而来,而不是被创建为等待问题发生的解决方案。微服务架构风格自然地从两个主要来源演变而来:使用分层架构模式开发的单片应用程序和通过面向服务的架构模式开发的分布式应用程序。
从单一应用程序到微服务架构风格的演进路径主要是通过持续交付的发展,持续部署的概念提出的。从开发到生产的管道,简化了应用程序的部署。单片应用程序通常由紧密耦合的组件组成,这些组件是单个可部署单元的一部分,使得繁琐且难以更改,测试和部署应用程序(因此,大多数大型IT商店中常见的“月度部署”周期的增加)。这些因素通常会导致脆弱的应用程序在每次部署新内容时都会中断。微服务架构模式通过将应用程序分成多个可部署单元(服务组件)来解决这些问题,这些单元可以独立于其他服务组件单独开发,测试和部署。
导致微服务架构模式的另一个演进路径来自实现面向服务架构模式(SOA)的应用程序中发现的问题。虽然SOA模式非常强大,并且提供了无与伦比的抽象级别,异构连接,服务编排以及将业务目标与IT功能相结合的承诺,但它仍然复杂,昂贵,无处不在,难以理解和实现,并且通常具有过度杀伤力适用于大多数应用 微服务架构风格通过简化服务概念,消除编排需求以及简化连接和访问服务组件来解决这种复杂性。
模式拓扑
虽然有几十种方法可以实现微服务架构模式,但三种主要拓扑结构是最常见和最流行的:基于 API REST的拓扑,基于应用程序REST的拓扑和集中式消息传递 拓扑。
API REST模式
基于API REST的拓扑对于通过某种API(应用程序编程接口)公开小型,独立的单个服务的网站非常有用。此拓扑结构如图4-2所示,由非常细粒度的服务组件(因此称为微服务)组成,其中包含一个或两个模块,这些模块独立于其他服务执行特定的业务功能。在此拓扑中,通常使用通过单独部署的基于Web的API层实现的基于REST的接口来访问这些细粒度服务组件。此拓扑的示例包括Yahoo,Google和Amazon发现的一些常见的基于云的单一用途RESTful Web服务。
图4-2。基于API REST的拓扑
REST应用程序模式
基于REST的应用程序拓扑与基于API REST的方法的不同之处在于,客户端请求是通过传统的基于Web或胖客户端的业务应用程序屏幕而不是通过简单的API层接收的。如在示出的图4-3,应用程序的用户界面层部署为单独的Web应用程序,通过简单的基于REST的界面远程访问单独部署的服务组件(业务功能)。此拓扑中的服务组件与基于API-REST的拓扑中的服务组件的不同之处在于,这些服务组件往往更大,更粗粒度,并且代表整个业务应用程序的一小部分,而不是细粒度,单一 - 行动服务。此拓扑对于复杂程度相对较低的中小型业务应用程序很常见。
图4-3。应用程序基于REST的拓扑
集中消息模式
微服务架构模式中的另一种常见方法是集中式消息传递拓扑。此拓扑(如图4-4所示)与先前基于REST的拓扑结构类似,不同之处在于此拓扑使用轻量级集中式消息代理(例如,ActiveMQ,HornetQ等),而不是使用REST进行远程访问。在查看此拓扑时,不要将其与面向服务的体系结构模式混淆或将其视为“SOA-Lite”,这一点非常重要。此拓扑中的轻量级消息代理不执行任何编排,转换或复杂路由;而是,它只是一个访问远程服务组件的轻量级传输。
集中式消息传递拓扑通常在较大的业务应用程序或需要对用户界面和服务组件之间的传输层进行更复杂控制的应用程序中找到。此拓扑优于先前讨论的基于REST的简单拓扑的优点是高级排队机制,异步消息传递,监视,错误处理以及更好的整体负载平衡和可伸缩性。通常与集中式代理相关联的单点故障和架构瓶颈问题通过代理群集和代理联合(将单个代理实例拆分为多个代理实例以根据系统的功能区域划分消息吞吐量负载)来解决。
图4-4。集中式消息传递拓扑
避免依赖和编排
微服务架构模式的主要挑战之一是确定服务组件的正确粒度级别。如果服务组件过于粗糙,您可能无法实现此体系结构模式带来的好处(部署,可伸缩性,可测试性和松散耦合)。但是,过于精细化的服务组件将导致服务编排要求,这将迅速将您的精益微服务架构转变为重量级的面向服务的架构,同时具备SOA所带来的所有复杂性,混乱,费用和漏洞。基础申请。
如果您发现需要在应用程序的用户界面或API层中编排服务组件,那么您的服务组件可能太精细了。同样,如果您发现需要在服务组件之间执行服务间通信以处理单个请求,那么您的服务组件可能过于细粒度,或者从业务功能角度来看,它们的分区不正确。
可以通过共享数据库来处理可能强制组件之间不期望的耦合的服务间通信。例如,如果处理Internet订单的服务组件需要客户信息,则它可以转到数据库以检索必要的数据,而不是调用客户服务组件中的功能。
共享数据库可以处理信息需求,但共享功能呢?如果服务组件需要包含在另一个服务组件中的功能或所有服务组件共有的功能,您有时可以跨服务组件复制共享功能(从而违反DRY原则:不要重复自己)。在大多数实现微服务架构模式的业务应用程序中,这是一种相当普遍的做法,为了保持服务组件独立并分离其部署,牺牲重复业务逻辑的一小部分的冗余。小实用程序类可能属于此类重复代码。
如果您发现无论服务组件的粒度级别如何,您仍然无法避免服务组件编排,那么这可能不是您的应用程序的正确架构模式的好迹象。由于此模式的分布式特性,在服务组件之间(和之间)维护单个事务工作单元非常困难。这种做法需要某种用于回滚事务的事务补偿框架,这为这种相对简单和优雅的架构模式增加了显着的复杂性。
注意事项
微服务架构模式解决了单片应用程序以及面向服务的体系结构中的许多常见问题。由于主要应用程序组件被分成较小的,单独部署的单元,因此使用微服务架构模式构建的应用程序通常更强大,提供更好的可伸缩性,并且可以更轻松地支持持续交付。
这种模式的另一个优点是它提供了进行实时生产部署的能力,从而大大减少了对传统的每月或周末“大爆炸”生产部署的需求。由于变化一般是分离特定的服务组件,只是更改服务组件需要进行部署。如果您只有一个服务组件实例,则可以在用户界面应用程序中编写专用代码,以检测活动的热部署并将用户重定向到错误页面或等待页面。或者,您可以在实时部署期间交换多个服务组件实例,从而在部署周期期间实现连续可用性(这对于分层体系结构模式非常困难)。
需要考虑的最后一个考虑因素是,由于微服务架构模式是分布式架构,因此它与事件驱动架构模式中存在的一些相同的复杂问题相同,包括合同创建,维护和政府,远程系统可用性以及远程访问身份验证和授权。
模式分析
整体敏捷
评级:高
分析:整体敏捷性是指能够快速响应不断变化的环境。由于单独部署的单元的概念,更改通常与单个服务组件隔离,这允许快速且容易的部署。此外,使用此模式构建的应用程序往往非常松散地耦合,这也有助于促进更改。
易于部署
评级:高
分析:总体而言,由于事件处理器组件的分离性,这种模式相对容易部署。代理拓扑往往比中介拓扑更容易部署,主要是因为事件介体组件与事件处理器有些紧密耦合:事件处理器组件的更改可能还需要更改事件介体,这两者都要求为任何给定的变化部署。
可测性
评级:高
分析:由于业务功能与独立应用程序的分离和隔离,可以确定测试范围,从而实现更有针对性的测试工作。对于特定服务组件的回归测试比整个单片应用程序的回归测试更容易,更可行。此外,由于此模式中的服务组件是松散耦合的,因此从开发角度来看,实现应用程序的另一部分的更改的可能性要小得多,从而减轻了必须测试整个应用程序的测试负担。更改。
性能
评级:低
分析:虽然您可以创建从此模式实现的执行得非常好的应用程序,但由于微服务架构模式的分布式特性,整体上这种模式自然不适合高性能应用程序。
可扩展性
评级:高
分析:由于应用程序被拆分为单独部署的单元,因此可以单独扩展每个服务组件,从而允许对应用程序进行微调。例如,由于该功能的用户量较低,股票交易应用程序的管理区域可能不需要扩展,但是由于大多数交易应用程序为此需要高吞吐量,交易放置服务组件可能需要扩展。功能。
易于开发
评级:高
分析:由于功能被隔离到独立且不同的服务组件中,因此范围较小且隔离,开发变得更容易。开发人员在一个服务组件中进行更改的可能性要小得多,这会影响其他服务组件,从而减少开发人员或开发团队之间所需的协调。
参考链接:https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch04.html