微服务 | Martin Fowler

  • 微服务架构的九大特性
    • 特性一:“组件化”与“多服务”
    • 特性二:围绕“业务功能”组织团队
    • 特性三:“做产品”而不是“做项目”
    • 特性四:智能端点和哑管道
    • 特性五:“去中心化”地治理技术
    • 特性六:“去中心化”地管理数据
    • 特性七:“基础设施”自动化
    • 特性八:为失效设计
    • 特性九:进化式设计
  • 未来的方向是“微服务”吗?

“微服务架构”这一术语在前几年横空出世,用于描述这样一种特定的软件设计方法,即以若干组可独立部署的服务的方式进行软件应用系统的设计。尽管这种架构风格尚无明确的定义,但其在下述方面还是存在一定的共性,即围绕业务功能的组织、自动化部署、端点智能、以及在编程语言和数据方面进行去中心化的控制。

微服务架构的九大特性

“微服务” - 软件架构拥挤大街上的有一个新术语。虽然我们自然的倾向是轻蔑的一瞥将它一带而过,然而我们发现这一术语描述了一种越来越吸引人的软件系统风格。我们已看到,在过去的几年中有许多项目使用了这种风格,并且到目前为止结果都还不错,以致于这已变成了我们同事在构建企业级应用程序时默认使用的架构风格。然而,遗憾的是并没有太多的信息来概述什么是微服务风格以及怎样用这种风格。

简单来说,微服务架构风格[是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。

与单体风格作对比有助于开始解释微服务风格:单体应用程序被构建为单一单元。企业级应用程序通常由三部分组成:客户端侧用户接口(由运行于开发机上的浏览器里的HTML页面和Javascript组成),数据库(由插入到通用关系型数据库管理系统中的许多数据表格组成),服务端应用程序。服务端应用程序处理HTTP请求,执行领域逻辑,从数据库中检索、更新数据,选择、填充将要发送到浏览器的HTTP视图。服务端应用程序是一个单一的逻辑可执行单体。系统的任何改变都将牵涉到重新构建和部署服务端的一个新版本。

这样的单体服务器是构建这样一个系统最自然的方式。处理请求的所有逻辑都运行在一个单一进程中,允许你使用编程语言的基本特性将应用程序划分类、函数和命名空间。你认真的在开发机上运行测试应用程序,并使用部署管道来保证变更已被正确地测试并部署到生产环境中。该单体的水平扩展可以通过在负载均衡器后面运行多个实例来实现。

单体应用程序可以是成功的,但人们日益对他们感到挫败,尤其是随着更多的应用程序被部署在云上。变更周期被捆绑在一起 —— 即使只变更应用程序的一部分,也需要重新构建并部署整个单体。长此以往,通常将很难保持一个良好的模块架构,这使得很难变更只发生在需要变更的模块内。程序扩展要求进行整个应用程序的扩展而不是需要更多资源的应用程序部分的扩展。

特性一:“组件化”与“多服务”

自我们从事软件行业以来,发现大家都有“把组件插在一起来构建系统”的愿望,就像在物理世界中所看到的那样。在过去几十年中,我们已经看到,在公共软件库方面已经取得了相当大的进展,这些软件库是大多数编程语言平台的组成部分。

当谈到组件时,会碰到一个有关定义的难题,即什么是组件?我们的定义是:一个组件就是一个可以独立更换和升级的软件单元。

微服务架构也会使用软件库,但其将自身软件进行组件化的主要方法是将软件分解为诸多服务。我们将软件库(libraries)定义为这样的组件,即它能被链接到一段程序,且能通过内存中的函数来进行调用。然而,服务(services)是进程外的组件,它们通过诸如web service请求或远程过程调用这样的机制来进行通信(这不同于许多面向对象的程序中的service object概念)。

以使用服务(而不是以软件库)的方式来实现组件化的一个主要原因是,服务可被独立部署。如果一个应用系统由在单个进程中的多个软件库所组成,那么对任一组件做一处修改,都不得不重新部署整个应用系统。但是如果该应用系统被分解为多个服务,那么对于一个服务的多处修改,仅需要重新部署这一个服务。当然这也不是绝对的,一些变更服务接口的修改会导致多个服务之间的协同修改。但是一个良好的微服务架构的目的,是通过内聚的服务边界和服务协议方面的演进机制,来将这样的修改变得最小化。

以服务的方式来实现组件化的另一个结果,是能获得更加显式的(explicit)组件接口。大多数编程语言并没有一个良好的机制来定义显式的发布接口。通常情况下,这样的接口仅仅是文档声明和团队纪律,来避免客户端破坏组件的封装,从而导致组件间出现过度紧密的耦合。通过使用显式的远程调用机制,服务能更容易地规避这种情况。

如此使用服务,也会有不足之处。比起进程内调用,远程调用更加昂贵。所以远程调用API接口必须是粗粒度的,而这往往更加难以使用。如果需要修改组件间的职责分配,那么当跨越进程边界时,这种组件行为的改动会更加难以实现。

近似地,我们可以把一个个服务映射为一个个运行时的进程,但这仅仅是一个近似。一个服务可能包括总是在一起被开发和部署的多个进程,比如一个应用系统的进程和仅被该服务使用的数据库。

特性二:围绕“业务功能”组织团队

当在寻求将一个大型应用系统分解成几部分时,公司管理层往往会聚焦在技术层面上,这就意味着要组建用户界面团队、服务器端团队和数据库团队。当团队沿着这些技术线分开后,即使要实现软件中一个简单的变更,也会发生跨团队的项目时延和预算审批。在这种情况下,聪明的团队会进行局部优化,“两害相权取其轻”,来直接把代码逻辑塞到他们能访问到的任意应用系统中。换句话说,这种情况会导致代码逻辑散布在系统各处。这就是康威定律的鲜活实例。

任何设计(广义上的)系统的组织,都会产生这样一个设计,即该设计的结构与该组织的沟通结构相一致。——梅尔文•康威(Melvyn Conway), 1967年


微服务采用不同的分割方法,划分成围绕业务能力组织的服务。这些服务采取该业务领域软件的宽栈实现,包括用户接口、持久化存储和任何外部协作。因此,团队都是跨职能的,包括开发需要的全方位技能:用户体验、数据库、项目管理。

www.comparethemarket.com是按这种方式组织的一个公司。跨职能团队负责创建和运营产品,产品被划分成若干个体服务,这些服务通过消息总线通信。

大型单体应用程序也总是可以围绕业务能力来模块化,虽然这不是常见的情况。当然,我们将敦促创建单体应用程序的大型团队将团队本身按业务线拆分。我们看到这种情况的主要问题是他们趋向于围绕太多的上下文进行组织。如果单体横跨了多个模块边界,对团队个体成员来说,很难把它们装进他们的短期记忆里。另外,我们看到模块化的路线需要大量的规则来强制实施。服务组件所要求的更加明确的分离,使得它更容易保持团队边界清晰。

一个微服务应该有多大?
虽然,“微服务”已成为这种架构风格的代称,这个名字确实会导致不幸的聚焦于服务的大小,并为“微”由什么组成争论不休。在与微服务实践者的对话中,我们发现有各种大小的服务。最大的服务报道遵循亚马逊两匹萨团队(也就是,整个团队吃两个披萨就吃饱了)的理念,这意味着团队不超过12个人。在更小的规模大小上,我们看到这样的安排,6人团队将支持6个服务。
.
这引出了一个问题,即“每12人做一个服务”和“每人做一个服务”这样有关服务规模的差距,是否已经大到不能将两者都纳入微服务之下?此时,我们认为最好还是把它们归为一类,但是随着探索的深入,我们将来极有可能会改变主意。

特性三:“做产品”而不是“做项目”

我们看到大多数应用程序开发工作使用一个项目模式:目标是交付将要完成的一些软件。完成后的软件被交接给维护组织,然后它的构建团队就解散了。

微服务支持者倾向于避免这种模式,而是认为一个团队应该负责产品的整个生命周期。对此一个共同的启示是亚马逊的理念 “you build, you run it” ,开发团队负责软件的整个产品周期。这使开发者经常接触他们的软件在生产环境如何工作,并增加与他们的用户联系,因为他们必须承担至少部分的支持工作。

产品思想与业务能力紧紧联系在一起。要持续关注软件如何帮助用户提升业务能力,而不是把软件看成是将要完成的一组功能。

没有理由说为什么同样的方法不能用在单体应用程序上,但服务的粒度更小,使得它更容易在服务开发者和用户之间建立个人关系。

特性四:智能端点和哑管道

当在不同的进程之间构建各种通信结构时,我们已经看到许多产品和方法,来强调将大量的智能特性纳入通信机制本身。其中一个典型例子,就是“企业服务总线”(Enterprise Service Bus, ESB)。ESB产品经常包括高度智能的设施,来进行消息的路由、编制(choreography)、转换,并应用业务规则。

微服务社区主张采用另一种做法:智能端点(smart endpoints)和傻瓜管道(dumb pipes)。使用微服务所构建的各个应用的目标,都是尽可能地实现“高内聚和低耦合”——他们拥有自己的领域逻辑,并且更像是经典Unix的“过滤器”(filter)那样来工作——即接收一个请求,酌情对其应用业务逻辑,并产生一个响应。这些应用通过使用一些简单的REST风格的协议来进行编制,而不去使用诸如下面这些复杂的协议,即"WS-编制"(WS-Choreography)、BPEL或通过位于中心的工具来进行编排(orchestration)。

微服务最常用的两种协议是:带有资源API的HTTP“请求-响应”协议,和轻量级的消息发送协议。对于前一种协议的最佳表述是:

成为Web,而不是躲着Web (Be of the web, not behind the web)——Ian Robinson

这些微服务团队在开发中,使用在构建万维网(world wide web)时所使用的原则和协议(并且在很大程度上,这些原则和协议也是在构建Unix系统时所使用的)。那些被使用过的HTTP资源,通常能被开发或运维人员轻易地缓存起来。

最常用的第二种协议,是通过一个轻量级的消息总线来进行消息发送。此时所选择的基础设施,通常是“傻瓜”(dumb)型的(仅仅像消息路由器所做的事情那样傻瓜)——像RabbitMQ或ZeroMQ那样的简单实现,即除了提供可靠的异步机制(fabric)以外不做其他任何事情——智能功能存在于那些生产和消费诸多消息的各个端点中,即存在于各个服务中。

在一个单块系统中,各个组件在同一个进程中运行。它们相互之间的通信,要么通过方法调用,要么通过函数调用来进行。将一个单块系统改造为若干微服务的最大问题,在于对通信模式的改变。仅仅将内存中的方法调用转换为RPC调用这样天真的做法,会导致微服务之间产生繁琐的通信,使得系统表现变糟。取而代之的是,需要用更粗粒度的协议来替代细粒度的服务间通信。

特性五:“去中心化”地治理技术

集中治理的一个后果是单一技术平台的标准化发展趋势。经验表明,这种方法正在收缩 - 不是每个问题都是钉子,不是每个问题都是锤子。我们更喜欢使用正确的工具来完成工作,而单体应用程序在一定程度上可以利用语言的优势,这是不常见的。

把单体的组件分裂成服务,在构建这些服务时可以有自己的选择。你想使用Node.js开发一个简单的报告页面?去吧。用C++实现一个特别粗糙的近乎实时的组件?好极了。你想换用一个更适合组件读操作数据的不同风格的数据库?我们有技术来重建它。

当然,仅仅因为你可以做些什么,而不意味着你应该这样做 - 但用这种方式划分系统意味着你可以选择。

团队在构建微服务时也更喜欢用不同的方法来达标。他们更喜欢生产有用的工具这种想法,而不是写在纸上的标准,这样其他开发者可以用这些工具解决他们所面临的相似的问题。有时,这些工具通常在实施中收获并与更广泛的群体共享,但不完全使用一个内部开源模型。现在git和github已经成为事实上的版本控制系统的选择,在内部开放源代码的实践也正变得越来越常见。

微服务和SOA
当我们谈起微服务时,一个常见的问题就会出现:是否微服务仅仅是十多年前所看到的“面向服务的架构”(Service Oriented Architecture, SOA)?这样问是有道理的,因为微服务风格非常类似于一些支持SOA的人所赞成的观点。然而,问题在于SOA这个词儿意味着太多不同的东西。而且大多数时候,我们所遇到的某些被称作"SOA"的事物,明显不同于本文所描述的风格。这通常由于它们专注于ESB,来集成各个单块应用。
特别地,我们已经看到如此之多的面向服务的拙劣实现——从将系统复杂性隐藏于ESB中的趋势,到花费数百万进行多年却没有交付任何价值的失败项目,到顽固抑制变化发生的中心化技术治理模型——以至于有时觉得其所造成的种种问题真的不堪回首。
当然,在微服务社区投入使用的许多技术,源自各个开发人员将各种服务集成到各个大型组织的经验。“容错读取”(Tolerant Reader)模式就是这样一个例子。对于Web的广泛使用,使得人们不再使用一些中心化的标准,而使用一些简单的协议。坦率地说,这些中心化的标准,其复杂性已经达到令人吃惊的程度。(任何时候,如果需要一个本体来管理其他各个本体,那么麻烦就大了。)
这种常见的SOA表现,已使得一些微服务的倡导者完全拒绝将自己贴上SOA的标签。尽管其他人会将微服务看作是SOA的一种形式,也许微服务就是以正确的形式来实现面向服务的SOA。不管是哪种情况,SOA意味着如此之多的不同事物,这表明用一个更加干净利落的术语来命名这种架构风格是很有价值的。

Netflix是遵守这一理念的很好的例子。尤其是,以库的形式分享有用的且经过市场检验的代码,这激励其他开发者用类似的方式解决相似的问题,同时还为采用不同方法敞开了大门。共享库倾向于聚焦在数据存储、进程间通信和我们接下来要深入讨论的基础设施自动化的共性问题。

对为服务社区来说,开销特别缺乏吸引力。这并不是说社区不重视服务合约。恰恰相反,因为他们有更多的合约。只是他们正在寻找不同的方式来管理这些合约。像Tolerant Reader和消费者驱动的契约(Consumer-Driven Contracts)这样的模式通常被用于微服务。
这些援助服务合约在独立进化。执行消费者驱动的合约作为构建的一部分,增加了信心并对服务是否在运作提供了更快的反馈。事实上,我们知道澳大利亚的一个团队用消费者驱动的合约这种模式来驱动新业务的构建。他们使用简单的工具定义服务的合约。这已变成自动构建的一部分,即使新服务的代码还没写。服务仅在满足合约的时候才被创建出来 - 这是在构建新软件时避免"YAGNI"困境的一个优雅的方法。围绕这些成长起来的技术和工具,通过减少服务间的临时耦合,限制了中心合约管理的需要。

多种编程语言,多种选择可能
JVM作为平台的成长就是在一个共同平台内混合语言的最新例子。几十年来,破壳到高级语言利用高层次抽象的优势已成为一种普遍的做法。如同下拉到机器硬件,用低层次语言写性能敏感的代码一样。然而,很多单体不需要这个级别的性能优化和常见的更高层次的抽象,也不是DSL的。相反,单体通常是单一语言的并趋向于限制使用的技术的数量。

特性六:“去中心化”地管理数据

数据管理的去中心化有许多不同的呈现方式。在最抽象的层面上,这意味着使系统间存在差异的世界概念模型。在整合一个大型企业时,客户的销售视图将不同于支持视图,这是一个常见的问题。客户的销售视图中的一些事情可能不会出现在支持视图中。它们确实可能有不同的属性和(更坏的)共同属性,这些共同属性在语义上有微妙的不同。

这个问题常见于应用程序之间,但也可能发生在应用程序内部,尤其当应用程序被划分成分离的组件时。一个有用的思维方式是有界上下文(Bounded Context)内的领域驱动设计(Domain-Driven Design, DDD)理念。DDD把一个复杂域划分成多个有界的上下文,并且映射出它们之间的关系。这个过程对单体架构和微服务架构都是有用的,但在服务和上下文边界间有天然的相关性,边界有助于澄清和加强分离,就像业务能力部分描述的那样。

久经考验的标准和执行标准
微服务的下述做法有点泾渭分明的味道,即他们趋向于避开被那些企业架构组织所制定的硬性实>施标准,而愉快地使用甚至传播一些开放标准,比如HTTP、ATOM和其他微格式的协议。

这里的关键区别是,这些标准是如何被制定以及如何被实施的。像诸如IETF这样的组织所管理的各种标准,只有达到下述条件才能称为标准,即该标准在全球更广阔的地区有一些正在运行的实现案例,而且这些标准经常源自一些成功的开源项目。
这些标准组成了一个世界,它区别于来自下述另一个世界的许多标准,即企业世界。企业世界中的标准,经常由这样特点的组织来开发,即缺乏用较新技术进行编程的经验,或受到供应商的过度影响。

特性七:“基础设施”自动化

在各个微服务之间将数据的职责进行“去中心化”的管理,会影响软件更新的管理。处理软件更新的常用方法,是当更新多个资源的时候,使用事务来保证一致性。这种方法经常在单块系统中被采用。

像这样使用事务,有助于保持数据一致性。但是在时域上会引发明显的耦合,这样一来,在多个服务之间处理事务时会出现一致性问题。分布式事务实现难度之大是不必多言的。为此,微服务架构更强调在各个服务之间进行“无事务”的协调。这源自微服务社区明确地认识到下述两点,即数据一致性可能只要求数据在最终达到一致,并且一致性问题能够通过补偿操作来进行处理。

对于许多开发团队来说,选择这种方式来管理数据的“非一致性”,是一个新的挑战。但这通常也符合在商业上的实践做法。通常情况下,为了快速响应需求,商家们都会处理一定程度上的数据“非一致性”,通过做某种反向过程来进行错误处理。只要修复错误的成本低于“保持更大的数据一致性却导致丢了生意所产生”的成本相比,那么进行这种“非一致性”地数据管理就是值得的。

特性八:为失效设计

使用服务作为组件的一个结果是,应用程序需要被设计成能够容忍服务失效。任何服务调用都可能因为供应者不可用而失败,客户端必须尽可能优雅的应对这种失败。与单体应用设计相比这是一个劣势,因为它引入额外的复杂性来处理它。结果是,微服务团队不断反思服务失效如何影响用户体验。Netflix的Simian Army在工作日诱导服务甚至是数据中心故障来测试应用程序的弹性和监测。

在生产环境中的这种自动化测试足够给大多数运营团队那种不寒而栗,通常在结束一周的工作之前。这不是说单体风格不能够进行完善的监测设置,只是在我们的经验中比较少见。

断路器和产品就绪代码
断路器(Circuit Breaker)与其他模式如Bulkhead和Timeout出现在《Release it!》中。这些模式是被一起实现的,在构建通信应用程序时,它们是至关重要的。这篇Netflix博文很好的解释了使用这些模式的应用程序。

既然服务随时都可能失败,那么能够快速检测故障,如果可能的话,能自动恢复服务是很重要的。微服务应用程序投入大量比重来进行应用程序的实时监测,既检查构形要素(每秒多少次数据请求),又检查业务相关指标(例如每分钟收到多少订单)。语义监测可以提供一套早期预警系统,触发开发团队跟进和调查。

这对微服务架构特别重要,因为微服务偏好编排和事件协作,这会带来突发行为。虽然很多专家称赞偶然涌现的价值,事实的真相是,突发行为有时可能是一件坏事请。监测对于快速发现不良突发行为是至关重要的,所以它可以被修复。

单体可以被构建成和微服务一样透明 - 事实上,它们应该是透明的。不同的是,你绝对需要知道在不同进程中运行的服务是否断开。对同一进程中的库来说,这种透明性是不大可能有用的。

同步调用”有害
一旦在一些服务之间进行多个同步调用,就会遇到宕机的乘法效应。简而言之,这意味着整个系统的宕机时间,是每一个单独模块各自宕机时间的乘积。此时面临着一个选择:是让模块之间调用异步,还是去管理宕机时间?在英国卫报网站,他们在新平台上实现了一个简单的规则——每一个用户请求都对应一个同步调用。然而在Netflix公司,他们重新设计的平台API将异步性构建到API的机制(fabric)中。
那些微服务团队希望在每一个单独的服务中,都能看到先进的监控和日志记录装置。例如显示“运行/宕机”状态的仪表盘,和各种运维、业务相关的指标。另外我们经常在工作中会碰到这样一些细节,即断路器的状态、当前的吞吐率和延迟,以及其他一些例子。

特性九:进化式设计

微服务从业者,通常有进化式设计背景并且把服务分解看做是进一步的工具,使应用程序开发者能够控制他们应用程序中的变更而不减缓变更。变更控制并不一定意味着变更的减少 - 用正确的态度和工具,你可以频繁、快速且控制良好的改变软件。

当你试图把软件系统组件化时,你就面临着如何划分成块的决策 - 我们决定分割我们的应用的原则是什么?组件的关键特性是独立的更换和升级的理念 这意味着我们要找到这样的点,我们可以想象重写组件而不影响其合作者。事实上很多微服务群组通过明确地预期许多服务将被废弃而不是长期演进来进一步找到这些点。

卫报网站是被设计和构建成单体应用程序的一个好例子,但它已向微服务方向演化。网站的核心仍是单体,但他们喜欢通过使用调用单体API构建的微服务添加新功能。这种方法对天然临时性的特性特别方便,比如处理体育赛事的专题页面。网站的这样一部分可以使用快速开发语言迅速的被放在一起,并且一旦赛事结束立即删除。在金融机构中,我们看到类似的方法,为一个市场机会添加新服务,并在几个月甚至几周后丢弃掉。

强调可替代性是模块设计更一般原则的一个特例,它是通过变更模式来驱动模块化的。你想保持在同一模块中相同时间改变的事情。系统中很少变更的部分应该和正在经历大量扰动的部分放在不同的服务里。如果你发现你自己不断地一起改变两个服务,这是它们应该被合并的一个标志。

把组件放在服务中,为更细粒度的发布计划增加了一个机会。对单体来说,任何变更都需要完整构建和部署整个应用程序。而对微服务来说,你只需要重新部署你修改的服务。这可以简化和加速发布过程。坏处是,你必须担心一个服务的变化会阻断其消费者。传统的集成方法试图使用版本管理解决这个问题,但是微服务世界的偏好是只把版本管理作为最后的手段。我们可以避免大量的版本管理,通过把服务设计成对他们的提供者的变化尽可能的宽容。

未来的方向是“微服务”吗?

Martin Fowler:
我们写这篇文章的主要目的,是解释有关微服务的主要思路和原则。在花了一点时间做了这件事后,我们清楚地认识到,微服务架构风格是一个重要的理念——在研发企业应用系统时,值得对它进行认真考虑。我们最近已经使用这种风格构建了一些系统,并且了解到其他一些团队也赞同并正在使用这种方法。

我们所了解到的那些在某种程度上可以被称作这种架构风格的实践先驱包括:亚马逊、Netflix、英国卫报、英国政府数字化服务中心、realestate.com.au、Forward和comparethemarket.com。2013年的技术大会圈子充满了各种各样的、正在转向可归类为微服务的公司案例——包括Travis CI。另外还有大量的组织,它们长期以来一直在做着我们认为可以归类为微服务的产品,却从未使用过这个名字(这通常被标记为SOA——尽管正如我们所说,SOA会表现出各种自相矛盾的形式)。

尽管有这些正面的经验,但这并不意味着我们确信微服务是软件架构未来的方向。尽管到目前为止,与单块应用系统相比,我们对于所经历过的微服务的评价是积极的,但是我们也意识到这样的事实,即能供我们做出完整判断的时间还不够长。

通常,架构决策所产生的真正效果,只有在该决策做出若干年后才能真正显现。我们已经看到由带着强烈的模块化愿望的优秀团队所做的一些项目,最终构建出一个单块架构,并在几年之内不断腐化。许多人认为,如果使用微服务就不大可能出现这种腐化,因为服务的边界是明确的,而且难以随意搞乱。然而,对于那些开发时间足够长的各种系统,除非我们已经见识得足够多,否则我们无法真正评价微服务架构是如何成熟的。

Martin Fowler:
我们的同事Sam Newman花了2014年的大部分时间撰写了一本书,来记述我们构建微服务的经验。如果想对这个话题进行更深入的了解,下一步就应该是阅读这本书。

有人觉得微服务或许很难成熟起来,这当然是有原因的。在组件化上所做的任何工作的成功度,取决于软件与组件的匹配程度。准确地搞清楚某个组件的边界位置应该出现在哪里,是一件困难的工作。演进式设计承认难以对边界进行正确定位,所以它将工作的重点放到了易于对边界进行重构之上。但是当各个组件成为各个进行远程通信的服务后,比起在单一进程内调用各个软件库,此时的重构就变得更加困难。跨越服务边界的代码移动就变得困难起来。接口的任何变化,都需要在其各个参与者之间进行协调。向后兼容的层次也需要被添加进来。测试也会变得更加复杂。

另一个问题是,如果这些组件不能干净利落地组合成一个系统,那么所做的一切工作,仅仅是将组件内的复杂性转移到组件之间的连接之上。这样做的后果,不仅仅是将复杂性搬了家,它还将复杂性转移到那些不再明确且难以控制的边界之上。在观察一个小型且简单的组件内部时,人们很容易觉得事情已经变得更好了,然而他们却忽视了服务之间杂乱的连接。

最后,还要考虑团队成员的技能水平。新技术往往会被技术更硬的团队所采用。对于技术更加过硬的团队而更有效的一项技术,不一定适用于技术略逊一筹的团队。我们已经看到大量这样的案例,那些技术略逊一筹的团队构建出了杂乱的单块架构。当这种杂乱发生到微服务身上时,会出现什么情况?这需要花时间来观察。一个糟糕的团队,总会构建一个糟糕的系统——在这种情况下,很难讲微服务究竟是减少了杂乱,还是让事情变得更糟。

我们听到一个合理的说法:不要一上来就以微服务架构做为起点。相反,要用一个单块系统做为起点,并保持其模块化。当这个单块系统出现了问题后,再将其分解为微服务。(尽管这个建议并不理想,因为一个良好的单一进程内的接口,通常不是一个良好的服务接口。)

因此,我们持谨慎乐观的态度来撰写此文。到目前为止,我们已经看到足够多的有关微服务风格的内容,并且觉得这是一条值得去跋涉的道路。我们不能肯定地说,道路的尽头在哪里。但是,软件开发的挑战之一,就是只能基于“目前手上拥有但还不够完善”的信息来做出决策。

若欲获取最新参考资料列表以得到更多信息,
请参见微服务资源指南:http://martinfowler.com/microservices/.

微服务 | Martin Fowler相关推荐

  1. 什么是微服务 Martin Fowler的microservices

    https://martinfowler.com/articles/microservices.html https://martinfowler.com/microservices/ 微服务,最早由 ...

  2. Microservices(微服务)--Martin Fowler

    原文链接:http://martinfowler.com/articles/microservices.html 译文(可从上方原文链接处进入,如下图):http://blog.cuicc.com/b ...

  3. 【译】微服务 - Martin Fowler--转载文章

    文章转载于:http://www.bdata-cap.com/newsinfo/1713874.html,分享学习,如有侵权,请联系删除. 原文是 Martin Fowler 于 2014 年 3 月 ...

  4. 与Susan Fowler探讨生产就绪微服务之问答

    Microservices.com Practitioners峰会是为从业者量身定制的微服务会议,峰会专注于介绍大规模采用微服务的实际应用.峰会将会于2017年1月31日在旧金山举行.演讲者包括来自U ...

  5. 【译】Monolith first —— Martin Fowler 对于微服务架构的看法

    转载文章,文章经 LiteCodes 授权,转载至本博客. 原文地址:[译]Monolith first -- Martin Fowler 对于微服务架构的看法 整体架构先行(Monolith fir ...

  6. Martin Fowler 微服务的原文翻译(转载)

    微服务 原文地址:Martin Fowler 微服务的原文 一个新的架构术语 "微服务架构"一词是在过去几年里涌现出来的,它用于描述一种独立部署的软件应用设计方式.这种架构方式并没 ...

  7. Martin Fowler关于微服务的原文翻译

    原文如下:http://martinfowler.com/articles/microservices.html 微服务 有关这个新的技术架构术语的定义 "微服务架构"这个术语最近 ...

  8. 微服务概念 概念提出者Martin Fowler的译文

    微服务 有关这个新的技术架构术语的定义 "微服务架构"这个术语最近几年横空出世,来描述这样一种特定的软件设计方法,即以若干组可独立部署的服务的方式进行软件应用系统的设计.尽管这种架 ...

  9. 微服务提倡者Martin Fowler关于微服务的原文翻译<转载>

    Martin Fowler 微服务 一个新的架构术语: Matin Fowler提倡的微服务架构文章 在过去的几年中,出现了"微服务结构"一词,用于描述架将软件应用程序设计为独立部 ...

最新文章

  1. 百度推送 android7.1,【SDK版本更新】Android SDK 5.7.1
  2. oracle复合索引介绍(多字段索引)
  3. [Python图像处理] 十二.图像几何变换之图像仿射变换、图像透视变换和图像校正
  4. python爬取知乎live_Python爬虫 - 简单抓取百度指数
  5. js学习总结----案例之多级菜单js版本
  6. java自定义外部接口_如何使用可外部化的接口在Java中自定义序列化
  7. 均值滤波python实现_python手写均值滤波
  8. 为什么说java是具有跨平台性
  9. 稳的一比,鸿蒙系统霸榜Github!
  10. css规则、选择器(基础、复合)/选择器优先级
  11. n元线性方程组解的情况及判别准则
  12. 语音识别-食物声音识别
  13. WeTest全球化服务,为使命召唤手游质量保驾护航
  14. 结果页要求用户复制链接进行分享 而不是直接调用浏览器分享API的原因
  15. 2022第九届生物发酵展(济南)3月召开,拓展生物发酵行业新机遇
  16. MySQL 8.0的预研清单和计划
  17. c语言输出一些好看的图形,[转]好看的图形
  18. 广州某IT公司HR招开发:“不加班的都是垃圾 ”
  19. 超详细的Storyboard的解析——Objective-C(IOS)
  20. 李笑来:“我们不要过度乐观”

热门文章

  1. 黑盒测试——NextDate函数测试(判定表驱动法)
  2. 2021-06-27微信公众号模板消息群发
  3. 看见的与看不见的,你看见了吗?——读《1493-物种大交换》
  4. Android给图像添加相框、圆形圆角显示图片、图像合成知识
  5. 大道至简,职场上做人做事做管理
  6. 有没有人拼团csdn学习会员~~
  7. 乐博Android客户端(新浪微博)1.01发布,欢迎各位童鞋试用
  8. 利用Civil3d导入桥梁中线至Revit中建立桥梁上部结构
  9. 网络层(三)构成超网
  10. ArcGIS Server中的各种服务