微服务论文:一种新定义的架构术语

在过去的几年中,出现了“微服务体系结构”一词,用于描述将软件应用程序设计为可独立部署的服务套件的特定方式。 尽管没有这种架构样式的精确定义,但是围绕业务能力,自动化部署,端点中的智能以及对语言和数据的分散控制,组织周围存在某些共同特征。

前言


“微服务”-在拥挤的软件体系结构大街上的又一个新名词。尽管我们的天性是轻蔑地掠过这些事物,但是这种术语描述了一种越来越受欢迎的软件系统样式。在过去的几年中,我们已经看到许多项目都使用这种样式,并且到目前为止,结果是积极的,以至于对于我们的许多同事来说,这已成为构建企业应用程序的默认样式。但是,令人遗憾的是,没有太多信息可以概述什么是微服务风格以及如何实现。

简而言之,微服务架构样式[1]是一种将单个应用程序开发为一组小服务的方法,每个小服务都在自己的进程中运行并与轻量级机制(通常是HTTP资源API)进行通信。这些服务围绕业务功能构建,并且可以由全自动部署机制独立部署。这些服务的集中管理几乎没有,它可以用不同的编程语言编写并使用不同的数据存储技术。

要开始解释微服务样式,将其与整体式样式进行比较很有用:作为一个单元构建的整体式应用程序。 企业应用程序通常由三个主要部分构建:客户端用户界面(由在用户计算机上的浏览器中运行的HTML页面和javascript组成)和数据库(由插入到常见的关系数据库管理中的许多表组成) 系统)和服务器端应用程序。 服务器端应用程序将处理HTTP请求,执行域逻辑,从数据库中检索和更新数据,以及选择并填充要发送到浏览器的HTML视图。 这个服务器端应用程序是一个整体-一个逻辑可执行文件[2]。 对系统的任何更改都涉及构建和部署新版本的服务器端应用程序。

这种整体服务器是构建此类系统的自然方法。您处理请求的所有逻辑都在单个过程中运行,从而使您可以使用语言的基本功能将应用程序划分为类,函数和名称空间。一定要小心,您可以在开发人员的便携式计算机上运行和测试应用程序,并使用部署管道来确保正确测试了更改并将其部署到生产中。您可以通过在负载均衡器后面运行许多实例来水平缩放整体。

整体应用程序可以成功,但是越来越多的人对它们感到沮丧,尤其是随着越来越多的应用程序部署到云中。变更周期捆绑在一起-对应用程序的一小部分进行更改,需要重建和部署整个整体。随着时间的流逝,通常很难保持良好的模块化结构,这使得很难保留只影响该模块中一个模块的更改。扩展要求扩展整个应用程序,而不是需要更多资源的部分应用程序。

图1:整体和微服务

这些挫败感导致了微服务架构的风格:将应用程序构建为服务套件。 除了服务可独立部署和可扩展之外,每个服务还提供了牢固的模块边界,甚至允许以不同的编程语言编写不同的服务。 他们也可以由不同的团队来管理。

我们并不声称微服务风格是新颖的或创新的,它的根源至少可以追溯到Unix的设计原理。 但是我们确实认为,没有足够的人考虑微服务架构,并且如果使用微服务架构,许多软件开发会更好。

微服务架构的特征


我们不能说对微服务架构风格有一个正式的定义,但是我们可以尝试描述我们认为适合该标签的架构的共同特征。 与任何概述通用特征的定义一样,并非所有微服务架构都具有所有特征,但是我们确实希望大多数微服务架构都具有大多数特征。 尽管我们的作者一直是这个相当松散的社区的活跃成员,但我们的意图是尝试描述我们在自己的工作以及我们所认识的团队的类似努力中所看到的东西。 特别是,我们并没有制定一些符合标准的定义。

通过服务进行组件化

自从我们从事软件行业以来,就一直希望通过将组件连接在一起来构建系统,这与我们在物理世界中看到事物的方式非常相似。在过去的几十年中,我们看到了在大多数语言平台中都包含的大量公共库概要中取得了长足的进步。

在谈论组件时,我们会遇到很难定义组件的定义的问题。我们的定义是,组件是可以独立替换和升级的软件单元。

微服务架构将使用库,但是它们将自己的软件组成组件的主要方式是分解为服务。我们将库定义为链接到程序并使用内存中的函数调用进行调用的组件,而服务则是与诸如Web服务请求或远程过程调用之类的机制进行通信的进程外组件。 (这与许多OO程序[3]中的服务对象的概念不同。)

使用服务作为组件(而不是库)的主要原因之一是服务是可独立部署的。如果您的应用程序[4]在单个过程中包含多个库,则对任何单个组件的更改都将导致必须重新部署整个应用程序。但是,如果该应用程序分解为多个服务,则可以预期许多单个服务的更改仅要求重新部署该服务。这不是绝对的,某些更改会更改服务接口,从而导致某种程度的协调,但是好的微服务架构的目的是通过服务契约的内聚性服务边界和演化机制来最大程度地减少这些。

将服务用作组件的另一个结果是更明确的组件接口。大多数语言都没有定义明确的发布接口的良好机制。通常,这是唯一的文档和纪律,可以防止客户端破坏组件的封装,从而导致组件之间的耦合过于紧密。通过使用显式的远程调用机制,服务可以更轻松地避免这种情况。

使用这样的服务确实有缺点。远程调用比进程内调用更昂贵,因此远程API需要更粗粒度,这通常更难使用。如果您需要更改组件之间的职责分配,那么跨越流程边界时,这种行为转移就很难做到。

初看起来,我们可以观察到服务映射到运行时进程,但这仅仅是初看起来。服务可能包含将始终一起开发和部署的多个流程,例如仅由该服务使用的应用程序流程和数据库。

围绕业务能力进行组织

当希望将大型应用程序拆分为多个部分时,管理人员通常将重点放在技术层,从而导致UI团队,服务器端逻辑团队和数据库团队。 当团队按这些方向分开时,即使是简单的更改也可能导致跨团队项目需要时间和预算批准。 精明的团队会围绕此问题进行优化,并减少两种弊端中的较小者-只需将逻辑强加到他们可以访问的任何应用程序中即可。 换句话说,逻辑无处不在。 这是康威定律[5]发挥作用的一个例子。

设计系统(广泛定义)的任何组织都将产生其结构是组织通信结构副本的设计。
——梅尔文·康威(Melvin Conway),1968年

图2:Conway定律的作用

微服务划分方法不同,分为围绕业务能力组织的服务。 此类服务针对该业务领域采用了软件的广泛实施,包括用户界面,持久性存储和任何外部协作。 因此,团队是跨职能的,包括开发所需的全部技能:用户体验,数据库和项目管理。

图3:团队边界加强了服务边界

以这种方式组织的一家公司是www.comparethemarket.com。 跨职能团队负责构建和操作每个产品,每个产品分为多个通过消息总线进行通信的单独服务。

大型单片应用程序也始终可以围绕业务功能进行模块化,尽管这种情况并不常见。 当然,我们会敦促组成一个整体应用程序的大型团队按照业务范围划分自己。 我们在这里看到的主要问题是,它们往往是围绕太多环境来组织的。 如果整体跨越了这些模块化边界中的许多边界,那么团队中的各个成员可能很难将其纳入他们的短期记忆中。 另外,我们看到模块化的生产线需要大量的纪律来实施。 服务组件所需的必要的,更明确的分隔使得更容易保持团队界限。

产品不是项目

我们看到的大多数应用程序开发工作都使用项目模型:目的是交付某些软件,然后将其视为已完成。完成后,将软件移交给维护组织,并解散构建该软件的项目团队。

微服务的支持者倾向于避免这种模式,而是倾向于团队应该在产品的整个生命周期内拥有产品的想法。这样做的一个共同灵感是亚马逊的“构建,运行”概念,其中开发团队对生产中的软件负全部责任。这使开发人员可以日常接触其软件在生产中的行为方式,并增加与用户的联系,因为他们必须承担至少一些支持负担。

产品的心态与业务能力的联系紧密相关。而不是将软件视为要完成的功能集,而是存在一种持续的关系,即问题是软件如何帮助其用户增强业务能力。

没有理由不能在整体应用程序中采用相同的方法,但是较小的服务粒度可以使在服务开发人员与其用户之间建立个人关系变得更加容易。

智能端点和哑管道(dumb pipes)

在不同流程之间建立通信结构时,我们已经看到许多产品和方法强调将重要的智慧纳入通信机制本身。 一个很好的例子是企业服务总线(ESB),其中ESB产品通常包括用于消息路由,编排,转换和应用业务规则的复杂工具。

微服务社区赞成一种替代方法:智能端点和哑管道。 从微服务构建的应用程序旨在尽可能地分离和具有凝聚力-它们拥有自己的域逻辑,并且在传统的Unix意义上更充当过滤器-接收请求,适当地应用逻辑并产生响应。 使用简单的RESTish协议而不是诸如WS-Choreography或BPEL之类的复杂协议或通过中央工具进行编排来对这些文件进行编排。

最常用的两种协议是带有资源API的HTTP请求响应和轻量级消息传递[8]。 第一个的最好表达是

出现在网络上,而不是在网络后面
——伊恩·罗宾逊(Ian Robinson)

微服务团队使用建立在万维网(很大程度上是Unix)上的原理和协议。通常,开发人员或操作人员只需很少的精力就可以缓存使用过的资源。

常用的第二种方法是通过轻量级消息总线进行消息传递。所选的基础结构通常是哑巴的(哑巴仅用作消息路由器)-简单的实现(例如RabbitMQ或ZeroMQ)除了提供可靠的异步结构外,所做的工作不多-智能终端仍然存在于生产和销售终端。消费信息;在服务中。

在整体中,组件在进程内执行,并且它们之间的通信是通过方法调用或函数调用进行的。将整体式服务转换为微服务的最大问题在于更改通信模式。从内存中方法调用到RPC的幼稚转换会导致健谈的通信,效果不佳。相反,您需要使用更粗略的方法来替换细粒度的通信。

分散治理

集中治理的后果之一是倾向于在单一技术平台上实现标准化。经验表明,这种方法是束手无策的-不是每个问题都是钉子,也不是每个解决方案都是锤子。我们更喜欢使用正确的工具来完成工作,而整体式应用程序可以在一定程度上利用不同的语言,但这并不常见。

将整体组件拆分为服务时,我们在构建每个组件时都可以选择。您想使用Node.js站起来一个简单的报告页面吗?去吧。 C ++是否特别适合近乎实时的组件?美好的。您想交换一种更适合某个组件的读取行为的数据库类型吗?我们拥有重建他的技术。

当然,仅仅因为您可以做某事,并不意味着您应该-而是通过这种方式对系统进行分区意味着您可以选择。

构建微服务的团队也倾向于采用其他方法来制定标准。他们宁愿使用有用的工具来生产其他开发人员可以用来解决与他们所面临的问题类似的问题的方法,而不是使用书面记录在纸上某个位置的一组定义的标准。这些工具通常是从实现中获取的,有时与更广泛的群体共享,但并非唯一地使用内部开放源代码模型。既然git和github已成为事实上的版本控制系统的选择,内部内部的开放源码实践也变得越来越普遍。

Netflix是遵循这种理念的组织的一个很好的例子。共享有用的,最重要的是,经过试验验证的代码,因为库鼓励其他开发人员以相似的方式解决类似的问题,但也为选择其他方法(如果需要)敞开了大门。共享库通常专注于数据存储,进程间通信以及我们在下面进一步讨论的基础架构自动化等常见问题。

对于微服务社区而言,开销尤其没有吸引力。这并不是说社区不重视服务合同。相反,因为它们往往更多。只是他们正在寻找管理这些合同的不同方法。诸如“容忍读者”和“消费者驱动的合同”之类的模式通常应用于微服务。这些援助服务合同是独立发展的。在构建过程中执行以消费者为导向的合同可以增强信心,并提供有关服务是否正常运行的快速反馈。的确,我们知道在澳大利亚有一个团队,该团队通过消费者驱动的合同来推动新服务的构建。他们使用简单的工具来定义服务合同。在为新服务编写代码之前,这已成为自动化构建的一部分。然后,仅将服务构建到满足合同要求的程度,这是一种优雅的方法,可在构建新软件时避免出现“ YAGNI” [9]困境。这些技术及其周围发展的工具通过减少服务之间的时间耦合来限制对中央合同管理的需求。

分散式治理的最高点也许是亚马逊推广的“构建/运行”精神。 团队负责他们构建的软件的所有方面,包括24/7全天候运行的软件。 这种责任级别的下放绝对不是常态,但我们确实看到越来越多的公司将责任推向开发团队。 Netflix是采用这种精神[11]的另一个组织。 您的寻呼机每天晚上3点醒来,肯定是在编写代码时专注于质量的强大动力。 这些想法尽可能远离传统的集中式治理模型。

分散数据管理

数据管理的分散化以多种不同的方式呈现。 从最抽象的层面讲,这意味着系统的世界概念模型将有所不同。 在大型企业中进行集成时,这是一个常见问题,客户的销售视图将与支持视图不同。 在销售视图中称为客户的某些内容可能根本不会出现在支持视图中。 那些具有相同属性的属性可能具有不同的语义,并且(更差的)公共属性具有不同的语义。

此问题在应用程序之间很常见,但也可能在应用程序内发生,特别是当该应用程序划分为单独的组件时。关于此的一种有用的思考方法是“有界上下文”的“域驱动设计”概念。 DDD将复杂域划分为多个有界上下文,并映射出它们之间的关系。此过程对于单片和微服务体系结构都是有用的,但是服务和上下文边界之间存在自然的关联,这有助于弄清这一点,并且正如我们在业务功能部分中所描述的那样,它加强了这种分离。

除了分散有关概念模型的决策外,微服务还分散了数据存储决策。整体应用程序倾向于使用单个逻辑数据库来存储持久性数据,而企业通常更喜欢跨多个应用程序使用单个数据库-这些决定中的许多决定是由供应商围绕许可的商业模型决定的。微服务更喜欢让每个服务管理自己的数据库,或者是相同数据库技术的不同实例,或者是完全不同的数据库系统-这种方法称为Polyglot Persistence。您可以在整体中使用多语种持久性,但是在微服务中它的出现频率更高。

将跨微服务的数据责任分散到管理更新的含义中。处理更新的常见方法是使用事务来确保更新多个资源时的一致性。这种方法通常在整料中使用。

使用这样的事务有助于保持一致性,但会带来明显的时间耦合,这在多个服务之间是有问题的。众所周知,分布式事务难以实现,因此,微服务体系结构强调服务之间的无事务协调,并明确认识到一致性可能只是最终的一致性,而问题只能通过补偿操作来解决。

对于许多开发团队来说,以这种方式选择管理矛盾是一个新的挑战,但这是通常与业务实践相匹配的挑战。企业通常会处理一定程度的不一致以快速响应需求,同时具有某种逆转流程来处理错误。只要解决错误的成本小于在更高的一致性下失去业务的成本,就可以进行权衡。

基础设施自动化

基础设施自动化技术在过去几年中发生了巨大的发展,尤其是云技术和AWS的发展降低了构建,部署和运营微服务的运营复杂性。

微服务正在构建的许多产品或系统,都是由具有持续交付及其先驱持续集成经验的团队构建的。以这种方式构建软件的团队广泛使用了基础架构自动化技术。如下所示的构建管道中对此进行了说明。

图5:基本构建管道(pipeline)

由于这不是有关持续交付的文章,因此我们在这里仅关注几个关键功能。 我们希望尽可能地放心我们的软件正在运行,因此我们运行了许多自动化测试。 升级工作软件的渠道意味着我们可以自动部署到每个新环境。

可以很轻松地在这些环境中构建,测试并推动一个整体应用程序。 事实证明,一旦您为自动化整体生产进行了投资,那么部署更多应用程序似乎就不再那么令人恐惧了。 请记住,CD的目的之一是使部署变得无聊,因此,只要它仍然无聊,它的一个或三个应用程序就无关紧要[12]。

我们看到团队使用广泛的基础架构自动化的另一个领域是在生产中管理微服务。 与我们上面的断言相反,只要部署很无聊,整体和微服务之间就不会有太大的区别,每种服务的运营前景可能会截然不同。

图6:模块部署通常会有所不同

失败的设计

将服务用作组件的结果是,需要对应用程序进行设计,以便它们可以容忍服务故障。 由于供应商不可用,任何服务呼叫都可能失败,客户必须尽可能优雅地响应此请求。 与单片设计相比,这是一个缺点,因为它引入了额外的复杂性来处理它。 结果是微服务团队不断反思服务故障如何影响用户体验。 Netflix的Simian Army在工作日内导致服务甚至数据中心发生故障,以测试应用程序的弹性和监视能力。

这种在生产中的自动化测试足以使大多数操作小组摆脱通常在下班前感到的寒意。这并不是说整体式的建筑风格无法实现复杂的监控设置-在我们的经验中这并不常见。

由于服务随时可能发生故障,因此能够快速检测到故障并在可能的情况下自动恢复服务非常重要。微服务应用程序非常注重应用程序的实时监控,同时检查架构元素(数据库每秒收到多少请求)和业务相关指标(例如每分钟收到多少订单)。语义监视可以为发生错误的情况提供预警系统,从而触发开发团队进行跟进和调查。

这对于微服务体系结构尤其重要,因为微服务偏爱编排和事件协作会导致紧急行为。尽管许多专家都赞扬意外出现的价值,但事实是,突然出现的行为有时可能是一件坏事。监视对于迅速发现不良紧急行为至关重要,因此可以对其进行修复。

整体组件可以像微服务一样透明地构建-实际上,它们应该如此。不同之处在于,您绝对需要知道在不同进程中运行的服务何时断开连接。对于在同一过程中的库,这种透明度不太可能有用。

微服务团队希望看到每个服务的复杂监视和日志记录设置,例如显示上/下状态的仪表板以及各种与业务和业务相关的指标。关于断路器状态,当前吞吐量和等待时间的详细信息是我们在野外经常遇到的其他示例。

进化设计

微服务从业人员通常来自进化设计的背景,并将服务分解视为进一步的工具,使应用程序开发人员能够控制其应用程序中的更改而不会减慢更改的速度。变更控制并不一定意味着减少变更-使用正确的态度和工具,您可以频繁,快速且控制良好地对软件进行变更。

每当您尝试将软件系统分解为组件时,您都会面临如何分割各个部分的决定-我们决定对应用程序进行分割的原则是什么?组件的关键特性是独立替换和可升级性的概念[13]-这意味着我们寻找可以想象的重写组件而又不影响其协作者的观点。实际上,许多微服务团队通过明确期望许多服务将被废弃而不是长期发展而将其进一步发展。

Guardian网站是一个应用程序的一个很好的例子,该应用程序是作为整体设计和构建的,但是已经朝着微服务的方向发展。 Monolith仍然是网站的核心,但是他们更喜欢通过构建使用Monolith的API的微服务来添加新功能。对于固有的临时功能(例如处理体育赛事的专用页面),此方法特别方便。可以使用快速开发语言将网站的此类部分快速组合在一起,并在活动结束后将其删除。我们已经在一家金融机构中看到了类似的方法,在这种方法中,为了获得市场机会而添加了新服务,而在几个月甚至几周后便将其丢弃。

这种对可替换性的强调是模块化设计的更一般性原理的特例,该原理通过变化的模式来驱动模块化[14]。您想在同一模块中同时保留更改的内容。系统中很少变化的部分应该与当前正在大量流失的部分提供不同的服务。如果您发现自己反复更改两个服务,则表明它们应该合并。

将组件放入服务中,为更精细的发布计划提供了机会。使用整体式的任何更改都需要完整构建和部署整个应用程序。但是,使用微服务时,您只需要重新部署您修改过的服务即可。这样可以简化并加快发布过程。缺点是您必须担心一项服务的更改会破坏其用户。传统的集成方法是尝试使用版本控制来解决此问题,但是微服务领域的首选是仅将版本控制作为最后的手段。通过设计服务以尽可能容忍其供应商的变更,我们可以避免很多版本控制。

微服务是未来吗?


我们撰写本文的主要目的是解释微服务的主要思想和原理。 通过花时间来做到这一点,我们清楚地认为微服务架构风格是一个重要的想法,值得企业应用认真考虑。 我们最近使用该样式构建了多个系统,并认识了其他使用并喜欢这种方法的系统。

我们所知道的以某种方式引领建筑风格的人包括亚马逊,Netflix,卫报,英国政府数字服务,realestate.com.au,Forward和comparethemarket.com。在2013年的会议巡回赛上,到处都有很多公司正在迁移到可归类为微服务的公司的例子,包括Travis CI。此外,许多组织长期以来一直在做我们称之为微服务的事情,但是却从未使用过这个名称。 (通常将其标记为SOA-尽管正如我们已经说过的,SOA有许多相互矛盾的形式。[15])

尽管有这些积极的经验,但是,我们并没有争辩说我们可以确定微服务是软件体系结构的未来方向。尽管到目前为止,与单片应用程序相比,我们的经验是积极的,但我们意识到,没有足够的时间来进行全面的判断。

通常,您做出体系结构决策的真正后果只有在您做出决策的几年后才能显现出来。我们已经看到了一个项目,在这个项目中,一个对模块化有强烈需求的优秀团队构建了一个整体式的架构,并且这种架构多年来一直在衰落。许多人认为,由于服务边界是明确的并且很难修补,因此微服务不太可能出现这种衰减。但是,直到我们看到足够的系统和足够的使用期限,我们才能真正评估微服务架构的成熟程度。

人们肯定会期望微服务的成熟度很差,这是有一定原因的。在进行组件化的任何努力中,成功都取决于软件在组件中的适应程度。很难确切地确定组件边界应位于何处。进化设计认识到正确设置边界的困难,因此易于重构它们的重要性。但是,当您的组件是具有远程通信的服务时,则重构要比进程内库困难得多。跨服务边界移动代码很困难,参与者之间的任何接口更改都必须协调,需要向后兼容,并且使测试变得更加复杂。

另一个问题是,如果组件组成不清晰,那么您要做的就是将复杂性从组件内部转移到组件之间的连接。这不仅可以解决复杂性问题,还可以将其转移到不太明确和难以控制的地方。当您查看一个小的,简单的组件的内部而又缺少服务之间的混乱连接时,很容易想到事情会变得更好。

最后,还有团队合作能力的因素。技能更强的团队倾向于采用新技术。但是,对于技能娴熟的团队而言,更有效的技术并不一定适用于技能娴熟的团队。我们已经看到了很多情况,即缺乏熟练的团队来构建凌乱的整体架构,但是花些时间来看看当微服务发生这种混乱时会发生什么。一个糟糕的团队总是会创建一个糟糕的系统-在这种情况下,很难说微服务是减少混乱还是使其变得更糟。

我们听到的一个合理的论据是,您不应该从微服务架构开始。取而代之的是从整体开始,使其保持模块化,一旦整体出现问题,将其拆分为微服务。 (尽管此建议并不理想,因为良好的进程内接口通常不是良好的服务接口。)

因此,我们对此持谨慎乐观的态度。到目前为止,我们已经对微服务风格有足够的了解,认为这可能是一条值得走的路。我们无法确定最终的结果,但是软件开发的挑战之一是只能根据当前必须掌握的不完善信息来做出决策。

脚注

1:2011年5月在威尼斯附近的软件架构师研讨会上讨论了“微服务”一词,以描述与会人员认为这是他们中许多人最近探索的一种通用架构风格。 2012年5月,同一小组决定将“微服务”作为最合适的名称。 James于2012年3月在克拉科夫的微服务(Java)和Unix Way的33rd学位上以案例研究的形式提出了其中的一些想法,与此同时,Fred George也做了类似的研究。 Netflix的Adrian Cockcroft将这种方法描述为“细粒度的SOA”,与本文中提到的许多其他人(乔·沃恩斯,丹尼尔·特霍斯特-诺斯,埃文·博特彻和格雷厄姆·塔克利)一样,在Web规模上是这种风格的先驱。

2:Monolith一词已被Unix社区使用了一段时间。它出现在《 Unix编程的艺术》中,描述了太大的系统。

3:许多面向对象的设计人员,包括我们自己,在域驱动设计的意义上将术语“服务对象”用于执行与实体无关的重要过程的对象。这与本文中如何使用“服务”是一个不同的概念。可悲的是,“服务”一词具有两种含义,我们必须忍受一词多义。

4:我们认为应用程序是一种社会结构,它将代码库,功能组和资金主体捆绑在一起。

5:原始论文可以在Melvin Conway的网站上找到

6:我们无法抗拒提及吉姆·韦伯(Jim Webber)关于ESB代表“ Egregious Spaghetti Box”的说法。

7:Netflix将链接明确化-直到最近才将其架构风格称为细粒度的SOA。

8:在规模极限时,组织经常转向二进制协议-例如protobufs。使用这些功能的系统仍具有智能端点,哑管道的特性,并且会在透明性与规模之间进行权衡。大多数网络媒体资源,当然也包括绝大多数企业,都不需要进行权衡取舍-透明度可以是一个很大的胜利。

9:“ YAGNI”或“您不需要它”是XP的原则,并劝告您不要添加功能,除非您知道自己需要这些功能。

10:我们断言整体式语言是单一语言,这有点使我们感到困惑-为了在当今的网络上构建系统,您可能需要了解JavaScript和XHTML,CSS,您选择的服务器端语言,SQL和ORM方言。几乎没有一种语言,但是您知道我们的意思。

11:在2013年11月在Flowcon上发表的精彩演讲中,Adrian Cockcroft特别提到了“开发人员自助服务”和“开发人员运行他们写的东西”(原文如此)。

12:我们在这里有点不稳定显然,在更复杂的拓扑中部署更多服务比部署单个整体要困难得多。幸运的是,模式降低了这种复杂性-尽管仍然必须对工具进行投资。

13:实际上,Daniel Terhorst-North将此样式称为可替换组件体系结构,而不是微服务。由于这似乎与某些特征有关,因此我们更喜欢后者。

14:肯特·贝克(Kent Beck)在实现模式中将这一点作为他的设计原则加以强调。

15:SOA几乎不是这段历史的根源我记得当本世纪初出现SOA术语时,有人说过“我们已经这样做了好几年了”。一种说法是,这种样式的根源是在企业计算的早期,COBOL程序通过数据文件进行通信的方式。在另一个方向上,人们可能会说微服务与Erlang编程模型是一样的东西,但适用于企业应用程序上下文。

(附)微服务和SOA

当我们谈论微服务时,一个常见的问题是这是否只是我们十年前看到的面向服务的体系结构(SOA)。这一点是有好处的,因为微服务风格与某些SOA拥护者所支持的风格非常相似。但是,问题在于SOA意味着太多不同的东西,而且在大多数情况下,我们遇到一种称为“ SOA”的东西,这与我们在此描述的样式有很大的不同,通常是由于着眼于过去用于ESB的原因。集成单片应用程序。

尤其是,我们已经看到了许多面向服务的拙劣实现,从倾向于将复杂性隐藏在ESB的[6]中,到失败的多年计划,这些计划花费了数百万美元且没有任何价值,到集中化的治理模型积极地抑制了变化,有时很难看清这些问题。

当然,微服务社区中使用的许多技术都是从开发人员在大型组织中集成服务的经验中获得的。容错读取器模式就是一个例子。使用网络的努力做出了贡献,使用简单的协议是从这些经验中获得的另一种方法-坦率地说,这种偏离中央标准的反应已经达到了复杂性。 (每当您需要一个本体来管理您的本体时,您就知道自己陷入了严重的麻烦。)

SOA的这种普遍表现导致一些微服务倡导者完全拒绝了SOA标签,尽管其他人认为微服务是SOA的一种形式[7],也许面向服务是正确的。无论哪种方式,SOA意味着如此不同的事实这一事实意味着拥有一个术语来更清晰地定义这种体系结构样式是很有价值的。

(附)多种语言,多种选择

JVM作为平台的增长只是在通用平台内混合语言的最新示例。 几十年来,通常都采用高级语言来利用高级抽象的优势。 顺便说一句,并在较低级别中编写对性能敏感的代码。 但是,许多巨石都不需要这种性能优化级别,也不需要DSL和更高级的抽象(这一点令我们沮丧)。 相反,整体语言通常是单一语言,趋势是限制使用的技术数量[10]。

你可能感兴趣的:(微服务论文:一种新定义的架构术语)