微服务架构到底是什么鬼?

戳蓝字“CSDN云计算”关注我们哦!640?wx_fmt=jpeg

摘自《微服务架构设计模式》

作者::[美] (Chris Richardson)

译者:喻勇 

导语:微服务架构如何与更广泛的软件架构概念相结合?什么是服务?服务的规模有多重要?为了回答这些问题,我们需要退后一步,看看软件架构的含义。

软件的架构是一种抽象的结构,它由软件的各个组成部分和这些部分之间的依赖关系构成。正如你将在本文中看到的,软件的架构是多维的,因此有多种方法可以对其进行描述。架构很重要的原因是它决定了应用程序的质量属性或能力。传统上,架构的目标是可扩展性、可靠性和安全性。但是今天,该架构能够快速安全地交付软件,这一点非常重要。你将了解微服务架构是一种架构风格,可为应用程序提供更高的可维护性、可测试性和可部署性。

我将通过描述软件架构的概念及其重要性来开始本文。接下来,我将讨论架构风格的概念。然后我将微服务架构定义为特定的架构风格。让我们从理解软件架构的概念开始。

1 软件架构是什么,为什么它如此重要

架构显然很重要。至少有两个专门讨论该主题的会议:O’Reilly的软件架构会议和SATURN会议。许多开发人员的目标是成为一名架构师。但什么是架构,为什么它如此重要?

为了回答这个问题,我首先定义术语软件架构的含义。之后,我将讨论应用程序的架构是多维的,并使用一组视图或蓝图进行描述。然后我将强调软件架构的重要性,因为它对应用程序的质量属性有显著的影响。

软件架构的定义

软件架构有很多定义。例如,维基百科上列举了大量的定义。我最喜欢的定义来自卡耐基梅隆大学软件工程研究所的Len Bass及其同事,他们在使软件架构成为一门学科方面发挥了关键作用。他们定义的软件架构如下:

计算机系统的软件架构是构建这个系统所需要的一组结构,包括软件元素、它们之间的关系以及两者的属性。

这显然是一个非常抽象的定义。但其实质是应用程序的架构是将软件分解为元素(element)和这些元素之间的关系(relation)。由于以下两个原因,分解很重要:

它促进了劳动和知识的分工。它使具有特定专业知识的人们(或多个团队)能够就应用程序高效地协同工作。

它定义了软件元素的交互方式。

将软件分解成元素以及定义这些元素之间的关系,决定了软件的能力。

软件架构的4+1视图模型

从更具体的角度而言,应用程序的架构可以从多个视角来看,就像建筑架构,一般有结构、管线、电气等多个架构视角。Phillip Krutchen在他经典的论文《Architectural Blueprints —The 4+1 View Model of Software Architecture》中提出了软件架构的4+1视图。图1展示的这套视图定义了四个不同的软件架构视图,每一个视图都只描述架构的一个特定方面。每个视图包括一些特定的软件元素和它们相互之间的关系。

640?wx_fmt=jpeg

图1 4+1视图模型使用四个视图描述应用程序的架构,并显示每个视图中的元素如何协作处理请求的场景

每个视图的目的如下:

  • 逻辑视图:开发人员创建的软件元素。在面向对象的语言中,这些元素是类和包。它们之间的关系是类和包之间的关系,包括继承、关联和依赖。

  • 实现视图:构建编译系统的输出。此视图由表示打包代码的模块和组件组成,组件是由一个或多个模块组成的可执行或可部署单元。在Java中,模块是JAR文件,组件通常是WAR文件或可执行JAR文件。它们之间的关系包括模块之间的依赖关系以及组件和模块之间的组合关系。

  • 进程视图:运行时的组件。每个元素都是一个进程,进程之间的关系代表进程间通信。

  • 部署视图:进程如何映射到机器。此视图中的元素由(物理或虚拟)计算机和进程组成。机器之间的关系代表网络。该视图还描述了进程和机器之间的关系。

除了这四个视图以外,4+1中的+1是指场景,它负责把视图串联在一起。每个场景负责描述在一个视图中的多个架构元素如何协作,以完成一个请求。例如,在逻辑视图中的场景,展现了类是如何协作的。同样,在进程视图中的场景,展现了进程是如何协作的。

4+1视图是描述应用程序架构的绝佳方式。每一个视图都描述了架构的一个重要侧面。场景把视图中的元素如何协作串联在一起。现在我们来看看为什么架构是如此重要。

为什么架构如此重要

应用程序有两个层面的需求。第一类是功能性需求,这些需求决定一个应用程序做什么。这些通常都包含在用例(use case)或者用户故事(user story)中。应用的架构其实跟这些功能性需求没什么关系。功能性需求可以通过任意的架构来实现,甚至是非常糟糕的大泥球架构。

架构的重要性在于,它帮助应用程序满足了第二类需求:非功能性需求。我们把这类需求也称之为质量属性需求,或者简称为“能力”。这些非功能性需求决定一个应用程序在运行时的质量,比如可扩展性和可靠性。它们也决定了开发阶段的质量,包括可维护性、可测试性、可扩展性和可部署性。为应用程序所选择的架构将决定这些质量属性。

2 什么是架构的风格

在物理世界中,建筑物的建筑通常遵循特定的风格,例如维多利亚式、美国工匠式或装饰艺术式。每种风格都是一系列设计决策,限制了建筑的特征和建筑材料。建筑风格的概念也适用于软件。David Garlan和Mary Shaw这两位软件架构学科的先驱定义了如下架构风格:

因此,架构风格根据结构组织模式定义了一系列此类系统。更具体地说,架构风格确定可以在该风格的实例中使用的组件和连接器的词汇表,以及关于如何组合它们的一组约束。

特定的架构风格提供了有限的元素(组件)和关系(连接器),你可以从中定义应用程序架构的视图。应用程序通常使用多种架构风格的组合。例如,在本节的后面,我将描述单体架构是如何将实现视图构造为单个(可执行与可部署)组件的架构样式。微服务架构将应用程序构造为一组松散耦合的服务。

分层式架构风格

架构的典型例子是分层架构。分层架构将软件元素按“层”的方式组织。每个层都有明确定义的职责。分层架构还限制了层之间的依赖关系。每一层只能依赖于紧邻其下方的层(如果严格分层)或其下面的任何层。

可以将分层架构应用于前面讨论的四个视图中的任何一个。流行的三层架构是应用于逻辑视图的分层架构。它将应用程序的类组织到以下层中:

  • 表现层:包含实现用户界面或外部API的代码。

  • 业务逻辑层:包含业务逻辑。

  • 数据持久化层:实现与数据库交互的逻辑。

分层架构是架构风格的一个很好的例子,但它确实有一些明显的弊端:

  • 单个表现层:它无法展现应用程序可能不仅仅由单个系统调用的事实。

  • 单一数据持久化层:它无法展现应用程序可能与多个数据库进行交互的事实。

  • 将业务逻辑层定义为依赖于数据持久化层:理论上,这样的依赖性会妨碍你在没有数据库的情况下测试业务逻辑。

此外,分层架构错误地表示了精心设计的应用程序中的依赖关系。业务逻辑通常定义数据访问方法的接口或接口库。数据持久化层则定义了实现存储库接口的DAO类。换句话说,依赖关系与分层架构所描述的相反。

让我们看一下克服这些弊端的替代架构:六边形架构。

关于架构风格的六边形

六边形架构是分层架构风格的替代品。如图2-2所示,六边形架构风格选择以业务逻辑为中心的方式组织逻辑视图。应用程序具有一个或多个入站适配器,而不是表示层,它通过调用业务逻辑来处理来自外部的请求。同样,应用程序具有一个或多个出站适配器,而不是数据持久化层,这些出站适配器由业务逻辑调用并调用外部应用程序。此架构的一个关键特性和优点是业务逻辑不依赖于适配器。相反,各种适配器都依赖业务逻辑。

640?wx_fmt=jpeg

图2 六边形架构的一个示例,它由业务逻辑和一个或多个与外部系统通信的适配器组成。业务逻辑具有一个或多个端口。处理来自外部系统请求的入站适配器调用入站端口。出站适配器实现出站端口,并调用外部系统

业务逻辑具有一个或多个端口(port)。端口定义了一组操作,关于业务逻辑如何与外部交互。例如,在Java中,端口通常是Java接口。有两种端口:入站和出站端口。入站端口是业务逻辑公开的API,它使外部应用程序可以调用它。入站端口的一个实例是服务接口,它定义服务的公共方法。出站端口是业务逻辑调用外部系统的方式。出站端口的一个实例是存储库接口,它定义数据访问操作的集合。

业务逻辑的周围是适配器。与端口一样,有两种类型的适配器:入站和出站。入站适配器通过调用入站端口来处理来自外部世界的请求。入站适配器的一个实例是Spring MVC Controller,它实现一组REST接口(endpoint)或一组Web页面。另一个实例是订阅消息的消息代理客户端。多个入站适配器可以调用相同的入站端口。

出站适配器实现出站端口,并通过调用外部应用程序或服务处理来自业务逻辑的请求。出站适配器的一个实例是实现访问数据库的操作的数据访问对象(DAO)类。另一个实例是调用远程服务的代理类。出站适配器也可以发布事件。

六边形架构风格的一个重要好处是它将业务逻辑与适配器中包含的表示层和数据访问层的逻辑分离开来。业务逻辑不依赖于表示层逻辑或数据访问层逻辑。

由于这种分离,单独测试业务逻辑要容易得多。另一个好处是它更准确地反映了现代应用程序的架构。可以通过多个适配器调用业务逻辑,每个适配器实现特定的API或用户界面。业务逻辑还可以调用多个适配器,每个适配器调用不同的外部系统。六边形架构是描述微服务架构中每个服务的架构的好方法。

分层架构和六边形架构都是架构风格的实例。每个都定义了架构的构建块(元素),并对它们之间的关系施加了约束。六边形架构和分层架构(三层架构)构成了软件的逻辑视图。现在让我们将微服务架构定义为构成软件的实现视图的架构风格。

2.1.3 微服务架构是一种架构风格

前面已经讨论过4+1视图模型和架构风格,所以现在可以开始定义单体架构和微服务架构。它们都是架构风格。单体架构是一种架构风格,它的实现视图是单个组件:单个可执行文件或WAR文件。这个定义并没有说明其他的视图。例如,单体应用程序可以具有六边形架构风格的逻辑视图。

模式:单体架构

将应用程序构建为单个可执行和可部署组件。请参阅:http://microservices.io/patterns/monolithic.html。

微服务架构也是一种架构风格。它的实现视图由多个组件构成:一组可执行文件或WAR文件。它的组件是服务,连接器是使这些服务能够协作的通信协议。每个服务都有自己的逻辑视图架构,通常也是六边形架构。图2-3显示了FTGO应用程序可能的微服务架构。此架构中的服务对应于业务功能,例如订单管理和餐馆管理。

模式:微服务架构

将应用程序构建为松耦合、可独立部署的一组服务。请参阅:http://microservices.io/patterns/microservices.html。

640?wx_fmt=jpeg

图3 FTGO应用程序可能的微服务架构。它由众多服务组成

微服务架构强加的一个关键约束是服务松耦合。因此,服务之间的协作方式存在一定限制。为了解释这些限制,我将尝试定义什么是服务,解释松耦合意味着什么,并告诉你为什么这很重要。

什么是服务

服务是一个单一的、可独立部署的软件组件,它实现了一些有用的功能。图2-4显示了服务的外部视图,在此示例中是Order Service。服务具有API,为其客户端提供对功能的访问。有两种类型的操作:命令和查询。API由命令、查询和事件组成。命令如createOrder()执行操作并更新数据。查询,如findOrderById()检索数据。服务还发布由其客户端使用的事件,例如OrderCreated。

服务的API封装了其内部实现。与单体架构不同,开发人员无法绕过服务的API直接访问服务内部的方法或数据。因此,微服务架构强制实现了应用程序的模块化。

微服务架构中的每项服务都有自己的架构,可能还有独特的技术栈。但是典型的服务往往都具有六边形架构。其API由与服务的业务逻辑交互的适配器实现。操作适配器调用业务逻辑,事件适配器对外发布业务逻辑产生的事件。

640?wx_fmt=jpeg

图4 服务具有封装实现的API。API定义了由客户端调用的操作。有两种类型的操作:命令用来更新数据,查询用来检索数据。当服务的数据发生更改时,服务会发布可供客户端订阅的事件

在本书第12章讨论部署技术时,你将看到服务的实现视图可以采用多种形式。该组件可以是独立进程,在容器中运行的Web应用程序或OSGI包、云主机或Serverless技术,等等。但是,一个基本要求是服务具有API并且可以独立部署。

什么是松耦合

微服务架构的最核心特性是服务之间的松耦合性。服务之间的交互采用API完成,这样做就封装了服务的实现细节。这允许服务在不影响客户端的情况下,对实现方式做出修改。松耦合服务是改善开发效率、提升可维护性和可测试性的关键。小的、松耦合的服务更容易被理解、修改和测试。

我们通过API来实现松耦合服务之间的协调调用,这样就避免了外界对服务的数据库的直接访问和调用。服务自身的持久化数据就如同类的私有属性一样,是不对外的。保证数据的私有属性是实现松耦合的前提之一。这样做,就允许开发者修改服务的数据结构,而不用提前与其他服务的开发者互相协商。这样做在运行时也实现了更好的隔离。例如,一个服务的数据库加锁不会影响另外的服务。但是你稍后就会看到在服务间不共享数据库的弊端,特别是处理数据一致性和跨服务查询都变得更为复杂。

共享类库的角色

开发人员经常把一些通用的功能打包到库或模块中,以便多个应用程序可以重用它而无须复制代码。毕竟,如果没有Maven或npm库,我们今天的开发工作都会变得更困难。你可能也想在微服务架构中使用共享库。从表面上看,它似乎是减少服务中代码重复的好方法。但是你需要确保不会意外地在服务之间引入耦合。

例如,想象一下多个服务需要更新Order业务对象的场景。一种选择是将该功能打包为可供多个服务使用的库。一方面,使用库可以消除代码重复。另一方面,如果业务需求的变更影响了Order业务对象,开发者需要同时重建和重新部署所有使用了共享库的服务。更好的选择是把这些可能会更改的通用功能(例如Order管理)作为服务来实现,而不是共享库。

你应该努力使用共享库来实现不太可能改变的功能。例如,在典型的应用程序中,在每个服务中都实现一个通用的Money类(例如用来实现币种转换等固定功能)没有任何意义。相反,你应该创建一个供所有服务使用的共享库。

服务的大小并不重要

微服务这个术语的一个问题是会将你的关注点错误地聚焦在微上。它暗示服务应该非常小。其他基于大小的术语(如miniservice或nanoservice)也是如此。实际上,大小不是一个重要的考虑因素。

更好的目标是将精心设计的服务定义为能够由小团队开发的服务,并且交付时间最短,与其他团队协作最少。理论上,团队可能只负责单一服务,因此服务绝不是微小的。相反,如果服务需要大型团队或需要很长时间进行测试,那么拆分团队或服务可能是有意义的。另外,如果你因为其他服务的变更而不断需要同步更新自己负责的服务,或者你所负责的服务正在触发其他服务的同步更新,那么这表明服务没有实现松耦合。你构建的甚至可能是一个分布式的单体。

微服务架构把应用程序通过一些小的、松耦合的服务组织在一起。结果,这样的架构提升了开发阶段的效率,特别是可维护性、可测试性和可部署性,这也就让组织的软件开发速度更快。微服务架构也同时提升了应用程序的可扩展性,尽管这不是微服务的主要目标。为了使用微服务架构开发软件,你首先需要识别服务,并确定它们之间如何协作。现在我们来看看如何定义一个应用程序的微服务架构。

 

4 总结

  • 架构决定了软件的各种非功能性因素,比如可维护性、可测试性、可部署性和可扩展性,它们会直接影响开发速度。

  • 微服务架构是一种架构风格,它给应用程序带来了更高的可维护性、可测试性、可部署性和可扩展性。

640?wx_fmt=png

福利

扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!

640?wx_fmt=jpeg

推荐阅读:

  • 上万条数据撕开微博热搜的真相!

  • IT公司老板落水,各部门员工怎么救??

  • HTML 30 年进化史

  • 读了鸿蒙 OS 的代码后,我发现优秀项目都有这个共性!

  • 字节跳动李航:自学机器学习,研究AI三十载,他说AI发展或进入平缓期

  • 主链增幅最高飚至 152%,主流币却惊现回落;以太坊发币速度持续放缓

真香,朕在看了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/522245.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

厉害了,蚂蚁金服!创造了中国自己的数据库OceanBase

摘要: 两万字长文带你了解关于OceanBase的一切!2008年,王坚从微软亚洲研究院常务副院长的位置上离职后,于当年9月加入了阿里巴巴集团担任首席架构师一职,负责集团技术架构以及基础技术平台建设。加入阿里没多久后&…

模型预测控制 索引超出数组元素的数目(0)。_C++基础总结(二):C++基本数据类型及流控制语句详解...

上次分享了hello world, 今天小编分享 C基本数据类型及流控制语句 ,建议大家收藏慢慢学习,同时希望对大家的C学习有所帮助。C 数组C 支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据…

ajax将数据显示在class为content的标签中_利用selenium实现自动翻页爬取某鱼数据

基本思路:首先用开发者工具找到需要提取数据的标签列表:利用xpath定位需要提取数据的列表然后再逐个提取相应的数据:保存数据到csv:利用开发者工具找到下一页按钮所在标签:利用xpath提取此标签对象并返回:调用点击事件,并循环上述过程:最终效果图:代码:from seleniu…

实体嵌入(向量化):用深度学习处理结构化数据

摘要: 本文详细阐述了深度学习如何来实现处理结构化数据的方法。嵌入源自于NLP(word2vec)中的单词学习,上图来自Aylien本博文将涉及机器学习中两个重复出现的问题:第一个问题是深度学习在图像和文本中都有较好的表现&a…

arcengine遍历属性表_Excel催化剂-遍历文件夹内文件信息特别是图像、音视频等特有信息...

在过往的功能中,有体现出在Excel上管理文件的极大优势,在文件的信息元数据中,有图片和音视频这两类特有的属性数据,此篇对过往功能的一个补充,特别增加了图片和音视频信息的遍历功能。使用场景在文件管理过程中&#x…

想要成为数据科学家?知道这11种机器学习算法吗?

摘要: 想要成为数据科学家?知道这十几种机器学习算法吗?赶快来了解一下吧,文中附各种算法的资源地址! 机器学习从业者都有不同的个性,虽然其中一些人会说“我是X方面的专家,X可以训练任何类型的…

Docker精华问答 | Consul是什么?

在计算机技术日新月异的今天, Docker 在国内发展的如火如荼。特别是在一线互联网公司 Docker 的使用是十分普遍的,甚至成为了一些企业面试的加分项,那么今天我们继续关于Docker 的精华问答。1Q:Consul是什么?A:Consul是一个分布式…

2020科目一考试口诀_二级建造师考试科目有哪些2020

2020二级建造师考试科目有哪些:2020年二级建造师考试设《建设工程施工管理》、《建设工程法规及相关知识》两个公共科目和《专业工程管理与实务》科目(包含六个专业类别,任选一科报考)。(一)《专业工程管理与实务》科目分为6个专业类别:建筑工…

机器学习用于金融市场预测难在哪?

摘要: 本文主要讲述了机器学习用于金融市场预测难在哪?——金融间序是典型的部分可见马尔科夫决策过程(POMDP) 数据分布 小样本 难以计算的数据 十分复杂 部分可见马尔科夫决策过程 推荐系统的相似性 结束思索金融市场已经成为最早…

full join 和full outer join_多表关联:公式展开、join、过滤条件的顺序

这是在实现多表关联时想到的。我们现在这套体系,实现多表关联比较复杂。如果Superset能官方支持多表关联,不知道会是什么样的方案,复杂度如何。在公式这个层面,没有关联条件,只有两个列、或者多个列,相互之…

异构计算助力客户春节webp图片编码

摘要: 背景与挑战 技博客 GigaOM 曾报道:YouTube 的视频略缩图采用 WebP 格式后,网页加载速度提升了 10%;谷歌的 Chrome 网上应用商店采用 WebP 格式图片后,每天可以节省几 TB 的带宽,页面平均加载时间大约…

发动机压缩比怎么计算公式_怎么判断发动机有积碳,发动机积碳多的症状有哪些...

经过时间的积累,积碳作为发动机的通病几乎无处不有,很多车主也对此十分头疼。不过,很多车主小白并不了解车辆积碳是如何产生的,更不知道如何判断发动机是否有积碳,其实发动机积碳多的症状很容易让车主误以为车辆出现其…

Kubernetes之路 1 - Java应用资源限制的迷思

摘要: 随着容器技术的成熟,越来越多的企业客户在企业中选择Docker和Kubernetes作为应用平台的基础。然而在实践过程中,还会遇到很多具体问题。本文分析并解决了Java应用在容器使用过程中关于Heap大小设置的一个常见问题。随着容器技术的成熟&…

你家的饮水机,到底可以有多脏?

戳蓝字“CSDN云计算”关注我们哦!作者 | 胡巍巍出品 | CSDN(ID:CSDNnews)几年前,笔者在一所培训学校工作。因为学生多、学校大,老师也多,自然办公室也多。这种情况下,学校为了省事&a…

java http get_我是如何进入阿里巴巴的-面向春招应届生Java面试指南(九)

基础篇基本功面向对象的特征1.final, finally, finalize 的区别 final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为f…

链表的快慢指针思想的解决

看接下来的一道题目 1、给定一个头结点为 head 的非空单链表,返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。 例子:[1,2,3,4,5] 返回中间节点3 [1,2,3,4,5,6] 返回中间节点4 我们该如何做呢,首先这里用到了快慢…

使用Helm 在容器服务k8s集群一键部署wordpress

摘要: Helm 是啥? 微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起&#xff…

Jupyter Notebook数据科学高效技巧

摘要: 本文有一些关于Jupyter Notebook的干货,希望看完文章可以给你带来收获当我学习有关深度学习的优秀的fast.ai课程时,我学到了很多适用于通用软件工程的干货。我写这篇文章是为了总结这些技巧并与你分享。1.Jupyter Notebook拓展标准的Ju…

格罗方德起诉台积电侵犯16项专利、影响巨大;中兴通讯与印尼Smartfren展开合作;网传FB开发新通讯应用Threads……...

关注并标星星CSDN云计算极客头条:速递、最新、绝对有料。这里有企业新动、这里有业界要闻,打起十二分精神,紧跟fashion你可以的!每周三次,打卡即read更快、更全了解泛云圈精彩newsgo go go 索尼将于9月5日在IFA 2019上…

JS之前台参数提交到后台,双引号转义为解决办法

问题描述 var param $("#searchForm").serializeJson(); 前台封装好了键值对形式的字符串,使用了EasyUI的treeGrid控件,传到后台后,双引号转义为" 解决办法 apache工具包common-lang中有一个很有用的处理字符串的工具类&am…