说在前面
好久没写博文了,心里痒痒(或许是换工作后,有点时间了吧)。
近期好像谈论微服务的人比較多,也開始学习一下。可是都有E文。看起来半懂不懂的。
Martinfowler的《
微服务》,也算是入门必读了。有人
翻译过,可是仅仅有一半。还是自己练练手吧。
微服务
“微服务架构”一词在过去几年里广泛的传播,它用于描写叙述一种独立部署的软件应用设计方式。这样的架构方式并没有很准确的定义。可是在业务能力、自己主动部署、端对端的整合、对语言及数据的分散控制上,却有着显著特征。
“微服务”----仅仅只是在满大街充斥的软件架构中的一新名词而已。虽然我们非常歧视这种东西。可是这玩意所描写叙述的软件风格,越来越引起我们的注意。在过去几年里,我们发现越来越多的项目開始使用这种风格,以至于我们身边的同事在构建企业应用时,把它理所当然的觉得这是一种默认开发形式。
然而,非常不幸,微服务风格是什么。应该怎么开发,关于这种理论描写叙述却非常难找到。
简而言之。微服务架构风格,就像是把小的服务开发成单一应用的形式,每一个应用执行在单一的进程中。并使用如HTTP这样子的轻量级的API。这些服务满足某需求,并使用自己主动化部署工具进行独立公布。
这些服务能够使用不同的开发语言以及不同数据存储技术,并保持最低限制的集中式管理。
開始介微服务风格前,先介绍总体风格:即把一个完整的应用当成一开发单元。企业应用通常包括三个部分:client界面(由
html、
javascript组成,使用浏览器进行訪问)、数据库(由很多的表组件构成一个通用的、相互关联的数据管理系统)、服务端应用。
服务端应用处理HTTP请求、运行领域逻辑、检索并更新数据库中的数据、使用适当的HTML视图发送给client。服务端应用是完整的 ---- 由单一的逻辑层次运行。系统中任务变更都会导到服务端的应用又一次编辑并公布一个新的版本号。
这种总体服务是这种构建系统的非常自然的方式。
尽管利用开发语基础特性会把应用封装成类、函数、命名空间,可是业务中全部逻辑都要在单一的进程中处理完毕。
在某些场景中。开发人员可能在的笔计本中开发、測试应用。然后利用部署通道来保证经过正常測试、公布的改动内容正确的公布的产品中。也能够使用横向扩展,通过负载均横系统将事个应用部署到多台server上。
总体风格的应用也是相当成功的。可是越来越多的人感觉到有点不妥,特别是在云中进行应用的公布时。变更公布周期被绑定了 ---- 原来能够划分成小的应用、小的须要的变更,须要统一的进行编译和公布。随着时间的推移,人们通常难于维护一种优美的模块化的结构,使得一个模块的变更非常难不会影响到其他的模块。进行扩展,也须要进行总体的扩展。而不能依据进行部分的扩展。
图1:整理架构与微服务架构
这些原因导致了微服务架构风格的出现:以服务构建应用。
由于服务能够独立部署、独立扩展。服务也能够提供模块化的边界,而且不同的使用也能够使用不同的开发语言。
服还能够以不同的周期进行管理。
微服务风格关不是我们发明的。也不是一个新的东西,它至少起源于Unix时代的设计原则。之所以这样,我们觉得仅仅是当时非常少人考虑过这样的风格,并认识到把软件使用这样的的风格能够带来很多其它的优点。
微服务风格的特性
我们没有办法对微服务风格进行准确的定义,可是我们能够偿试着描写叙述一下微服务风格所应该具有的觉特性。这样就能够对它打上对应的标签了。
正如其他定义中对特性的描写叙述一新。并非全部的微服务风格都要全部的特性。可是我们觉得常见的微服务都应该有这些特性。虽然我们是相当松散的社区核心成员。可是我们也计划偿试描写叙述我们工作中或者在其他我们了解的组件中所理解的微服务。
当然,我们并不依赖于那些已经明白过的定义。
组件与服务
自从我们从事软件行业以来。一直希望可以构建由组件组成的系统,就像我们所示实现世界由物件构成的一样。在过去的几十年里。我们已经看到了大部分语言平台的公共库的进行了精简,并取得可观的进展。
当我们谈论组件的时候。有可能会由于组件的不同定义引起混乱。因此我们申明,这里谈到的组件是指软件中独立的单元,它能独立替代和独立更新。
微服务架构也使用组件库,可是它把软件拆分成服务,并觉得这是基本的组织形式。我们把组件库定义为程序中相互关系、并使用内存中调用的组件,把服务定义为进程间使用如Web请求服务或者远程调用来相互通信的组件。(这样的定义的方式与其他面向对象程序中服务对象的概念是不一样的。)
把服务当成组件(而不是组件库)一个基本的原因是服务能够独立的部署。假设你的应用由多个组件库组成并跑在一个进程中。那么不论什么组件的变更都将导致总体应用的又一次公布。可是假设由很多服务构成的应用,你能够想像的到每一个服务的变更仅须要公布对应的服务。当然。这也不是绝对的,比方导致服务接口的变更的更新就须要对应服务的变化。但优秀微服务构架,会尽量避免这样的服务间的耦合并完好服务的交互接口。
把服务当成组件的还有一个考虑是这将拥有更新清晰的接口。很多开发语言并没有良好的定义公共接口的机制。
通常仅仅有文档和规范说明,让用户避免组件间会导致组件耦合的过度的依赖。只是服务由是是通过明白的远程接口调用。这个问题就非常easy攻克了。
使用服务也有它的不足之处。
远程调用比进制内部调用更消耗性能,并且远程的API比較粗糙。难以使用。假设因为对组件的职责进行变更,影响到跨进程间的交互,那么这操作起来也比較困难。
第一个可能的特性。我们看到每一个服务是执行在独立的进程上的。注意,这仅仅是第一个可能的特性。服务也能够由多个进程组成。它们是同一时候开发和部署的,比如服务可能用到一个应用进制和一种数据禀。
环绕业务功能进行组织
当寻找把一个大的应用拆分成小的部分时,主管通常注意在技术层面。拆分成UI组、服务逻辑组和数据库组。当使用这样的标准对团队进行划分时,甚至小小的更变都将导致跨团队间项目协作。从而消耗时间和预算审批。
一个高效的团队会针对这样的情况进行改善。关注它们所涉及的应用逻辑,并从中做出较好的选择。
换句话说。逻辑无处不在。Conway‘s Law的实践就是一个样例。
不论什么组织设计一个系统(广义上的系统)都会产生一种设计,其结构为其组织通信结构的复本。
-- Melvyn Conway, 1967
图2:Conway‘s Law的实践
微服务更倾向于环绕业务功能对服务结构进行划分、拆解。这种服务,是针对业务领域有着关完整实现的软件,它包括使用接口、持久存储、以及对旬的交互。因此团队应该是跨职能的,包括完整的开发技术:用户体验、数据库、以及项目管理。
图3:通过团队边界强调服务边界
www.comparethemarket.com就採用这样的组织形式。
不同职能的团队同一时候为各自的产品构建和运营负责,同一时候每一个产品又拆分成多个通过消息引擎通信的单独服务。
大型的总体型应用也能够按照业务功能进行模块化的。虽然这样的样例不常见。
当然,我们敦促一个大型的团队将一个构建成总体型的应用按照业务功能进行拆分。
我们能看到主要问题在于。这样的组件形式会导致非常多的上下文依赖。假设在大量的模块边界上都存在这样的大量的调用。对于团队的每一个成员来说,短期内是非常难记住的。
此外。我们发现模块化方式须要大量的规范去强制运行,当然。大量明白的拆分也让服务组件在团队的边界中更加清晰。
产品不是项目
大部分的软件开发人员都使用这种开发模式:至力于提供一些被觉得是完整的软件。一旦开发完毕,软件将移交给维护部门。然后,开发组就能够解散掉了。
微服务的支持者觉得。这样的做法是不可取的。并提议开发组应该负责产品的整个生命周期。一个常见的证明是:Amazon的“你编译,你运维(you build, you run it)”的理念。它要求开发团队对软件产品的整个生命周期负责。
这要求开发人员每天都关注软件产品的执行情况,并与用户联系的更紧密。同一时候承担一些售后支持。
成熟的产品会与业务功能进行绑定。除了把软件看成既定功能的集合外,会进一步关心“软件怎样帮助用户实现业务功能”这种问题。
採用总体型的架构并非没有原因的,可是越小的服务粒度越easy促进用户与服务提供商之前的关系。
强化终端及弱化通道
当构建不同的进程间通信机制的时候,我们发现有很多的产品和方法可以把更加有效方法强增加的通信机制中。比方企业服务总线(ESB),这种产品提供更有效的方式改进通信过程中的路由、编码、传输、以及业务处理规则。
微服务倾向于做例如以下的选择:强化终端及弱化通道。
微服务的应用致力松耦合和高内聚:採用单独的业务逻辑,表现的更像经典Unix意义上的过滤器一样。接受请求、处理业务逻辑、返回响应。它们更喜欢简单的REST风格,而不是复杂的协议。如WS或者BPEL或者集中式框架。
有两种协议最常常被使用到:包括资源API的HTTP的请求-响应和轻量级消息通信协议。
最为重要的建议为:
Be of the web, not behind the web(善于利用网络,而不是限制使用网络。)
---- Ian Robinson
微服务团队採用这种原则和规范:基于互联网(广义上,包括Unix系统)构建系统。
这样常常使用的资源差点儿不用什么的代价就能够被开发人员或者执行商缓存。
另外一种做法是通过轻量级消息总线来公布消息。
这种的通信协议很的单一(单一到仅仅负责消息路由)。像RabbitMQ或者ZeroMQ这种简单的实现甚至像可靠的异步机制都没提供,以至于须要依赖产生或者消费消息的终端或者服务来处理这类问题。
在总体工风格中。组件在进程内运行,进程间的消息通信通常通过调用方法或者回调函数。从总体式风格到微服务框架最大的问题在于通信方式的变更。从内存内部原始的调用变成远程调用。产生的大量的不可靠通信。因此,你须要把粗粒度的方法成更加细粒度的通信。
分散治理
集中治理的一种优点是在单一平台上进行标准化。
经验表明这样的趋势的优点在缩小。由于并非全部的问题都同样,并且解决方式并非万能的。我们更加倾向于採用适当的工具解决适当的问题,总体式的应用在一定程度上比多语言环境更有优势,但也适合全部的情况。
把总体式框架中的组件。拆分成不同的服务,我们在构建它们时有很多其它的选择。
你想用Node.js去开发报表页面吗?做吧。用C++来构建时时性要求高的组件?非常好。
你想以在不同类型的数据库中切换,来提高组件的读取性能?我们如今有技术手段来实现它了。
当然,你是能够做很多其它的选择,但也不意味的你就能够这样做,由于你的系统使用这样的方式进行侵害意味着你已经有的决定。
採用微服务的团队更喜欢不同的标准。他们不会把这些标准写在纸上,而是喜欢这种思想:开发实用的工具来解决开发人员遇到的相似的问题。这些工具通常从实现中成长起来,并进行的广泛范围内分享,当然。它们有时,并不一定。会採用开源模式。如今开源的做法也变得越来越普遍,git或者github成为了它们其实的版本号控制系统。
Netfix就是这种一个组织。它是很好的一个样例。
分享实用的、尤其是经过实践的代码库激励着其他的开发着也使用相似的方式来解决相似的问题,当然,也保留着依据须要使用不同的方法的权力。共享库更关注于数据存储、进程内通信以及我们接下来做讨论到的自己主动化等这些问题上。
微服务社区中,开销问题特别引人注意。这并非说。社区不觉得服务交互的价值。
相反,正是由于发现到它的价值。这使得他们在寻找各种方法来解决它们。
如Tolearant Reader和Consumer-Driven
Contracts这种设计模式就常常被微服务使用。这些模式攻克了独立服务在交互过程中的消耗问题。
使用Consumer-Driven Contracts添加了你的信心,并实现了高速的反馈机制。其实。我们知道澳大利亚的一个团队致力使用Consumer-Drvien Contracts开发新的服务。
他们使用简单的project,帮助他们定义服务的接口。
使得在新服务的代码開始编写之前,这些接口就成为自己主动化构建的一个部分。构建出来的服务,仅仅须要指出这些接口适用的范围。一个优雅的方法避免了新软件中的‘YAGNI ‘困境。这些技术和工具在使用过程中完好,通过降低服务间的耦合,限制了集中式管理的需求。
或许分散治理普及于亚马逊“编译它,运维它”的理念。
团队为他们开发的软件负所有责任。也包括7*24小时的执行。全责任的方式并不常见。可是我们确实发现越来越多的公司在他们的团队中所推广。Netfix是另外一个接受这样的理念的组件。每天凌晨3点被闹钟吵醒,由于你很的关注写的代码质量。这在传统的集中式治理中这是一样多么不思议的事情呀。
分散数据管理
对数据的分散管理有多种不同的表现形式。最为抽象层次。它意味着不同系统中的通用概念是不同的。这带来的觉问题是大型的跨系统整合时,用户使用不同的售后支持将得到不同的促销信息。这样的情况叫做并没有给用户显示全部的促销手段。不同的语法确实存在同样的词义或者(更差)同样的词义。
应用之间这个问题非常普遍。但应用内部这个问题也存在,特别是当应用拆分成不同的组件时。对待这个问题非常实用的方式为
Bounded Context的领域驱动设计。DDD把复杂的领域拆分成不同上下文边界以及它们之间的关系。
这种过程对于总体架构和微服务框架都非常实用,可是服务间存在着明显的关系。帮助我们对上下文边界进行区分,同一时候也像我们在业务功能中谈到的,强行拆分。
当对概念模式下决心进行分散管理时,微服务也决定着分散数据管理。
当总体式的应用使用单一逻辑数据库对数据持久化时,企业通常选择在应用的范围内使用一个数据库,这些决定也受厂商的商业权限模式驱动。微服务让每一个服务管理自己的数据库:不管是同样数据库的不同实例,或者是不同的数据库系统。这样的方法叫Polyglot
Persistence。
你能够把这样的方法用在总体架构中,可是它更常见于微服务架构中。
图4:Polyglot Persistence
微服务音分散数据现随意味着管理数据更新。
处理数据更新的经常用法是使用事务来保证不同的资源改动数据库的一致性。这样的方法通常在总体架构中使用。
使用事务是由于它可以帮助处理一至性问题,但对时间的消耗是严重的,这给跨服务操作带来难题。
分布式事务很难以实施,因此微服务架构强调服务间事务的协调,并清楚的认识一致性仅仅能是终于一致性以及通过补偿运算处理问题。
选择处理不一致问题对于开发团队来说是新的挑战。可是也是一个常见的业务实践模式。通常业务上同意一定的不一致以满足高速响应的需求。但同一时候也採用一些恢复的进程来处理这样的错误。当业务上处理强一致性消耗比处理错误的消耗少时。这样的付出是值的的。
基础设施自己主动化
基础设施自己主动化技术在过去几年中得到了长足的发展:云计算,特别是AWS的发展,降低了构建、公布、运维微服务的复杂性。
很多使用微服务架构的产品或者系统。它们的团队拥有丰富的
持集部署以及它的前任
持续集成的经验。团队使用这样的方式构建软件致使更广泛的依赖基础设施自己主动化技术。
下图说明这样的构建的流程:
图5:主要的构建流程
虽然这不是介绍自己主动部署的文章。但我们也打算介绍一下它的主要特征。我们希望我们的软件应该这样方便的工作,因此我们须要很多其它的自己主动化測试。
流程中工作的软件改进意味着我们能自己主动的部署到各种新的环境中。
总体风格的应用相当开心的在各种环境中构建、測试、公布。
事实证明,一旦你打算投资一条总体架构应用自己主动化的的生产线,那么你会发现公布很多其它的应用似乎非不那么的可怕。
记住。CD(持续部署)的一个目标在于让公布变得无趣,因此不管是一个还是三个应用,它都一样的无趣。
还有一个方面,我们发现使用微服务的团队更加依赖于基础设施的自己主动化。相比之下。在总体架构也微服务架构中。虽然公布的场景不同,但公布工作的无趣并没有多大的差别。
图6:模块化部署的差别
容错性设计
使用服务作为组件的一个结果在于应用须要有能容忍服务的故障的设计。任务服务可能由于供应商的不可靠而故障,client须要尽可能的优化这样的场景的响应。跟总体构架相比,这是一个缺点,由于它带来的额外的复杂性。这将让微服务团队时刻的想到服务故障的情况下用户的体验。Netflix的
Simian Army能够为每一个应用的服务及数据中心提供日常故障检測和恢复。
这样的产品中的自己主动化測试能够让大部分的运维团队正常的上下班。这并不意味着总体构架的应用没有这么静止的监控配置,仅仅是在我们的经验中它并不常见。
因为服务能够随时故障,高速故障检測,乃至,自己主动恢复变更很重要。微服务应用把实时的监控放在应用的各个阶段中,检測构架元素(每秒数据库的接收的请求数)和业务相关的指标(把分钟接收的定单数)。监控系统能够提供一种早期故障告警系统,让开发团队跟进并调查。
对于微服务框架来说。这相当重要,由于微服务相互的通信可能导致紧急意外行为。
很多专家车称赞这样的紧急事件的价值,但事实是这样的紧急行为有时是灾难。监控是至关重要的。它能高速发现这样的紧急不良行为,让我们迅速修复它。
总体架构。跟微服务一样,在构建时是通明的,实情上,它们就是这样子的。它们不同之处在于。你须要清楚的认识到不同进程间执行的服务是不相关的。库对于同一进程是透明的,也因此不那么重要了。
微服务团队期望清楚的监控和记录每一个服务的配置。比方使用仪表盘显示上/下线状态、各种运维和业务相关的指标。对断路器(circuit breaker)状态、眼下的吞吐量和时延细节,我们也会常常遇到。
设计改进
微服务实践者。通常有不断改进设计的背景。他们把服务分解成进一步的工具。
这些工具能够让应用开发人员在不改变速度情况下。控制都他们的应用的需求变更。变更控制不意味首降低变更,而是使用适当的方式和工具,让它更加频繁。至少。非常好让它变得可控。
不论怎样,当你试图软件系统拆分成组件时,你将面临着怎样拆分的问题。那么我们的决定拆分我们应用的原则是什么呢?首要的因素,组件可以被独立替换和更新的。这意味着我们寻找的关键在于,我们要想象着重写一个组件而不影响它们之前的协作关系。其实。很多的微服务小组给它进一步的预期:服务应该可以报废的,而不是要长久的发展的。
Guardian站点就是这方面的一个优秀的样例,它初期被设计和构建成一个总体架构。但它已经向微服务的发展了。总体构架仍然是它站点的核心,可是他们使用微服务来添加那些使用总体架构API的新特性。这样的方法添加这些暂时的特性很方便,比方运动新闻的特稿。
这样站点的一个部分能够使用高速的开发语言迅速整合起来。当它过时后能够一次性移除。我们发现一家金融机构用相似的方法添加新的市场营销活动,数周或者几个月后把它撤销。
可取代是模块化开发中的一个特例,它是用模块来应对须要变更的。
你希望让变更是同样模块,同样周期中进行变化而已。系统的某些非常小做变更部分,也应该放在不同的服务中。这样它们更easy让它们消亡。
假设你发现两个服务一直反复的变更时。这就是一个要合并它们的信号了。
把组件改成服务,添加了细化公布计划的一个机会。
总体构架的任务变更须要整个应用的完整的构建和公布。
然而,使用微服务,你仅仅须要公布你要改动的服务就能够了。这将简化和加速你的公布周期。
缺点是你须要为一个变更服务公布可能中断用户的体验而操心。
传统的集成方法是使用版本号来处理这些问题。可是微服务版本号仅是最后的通告手段。我们须要在设计服务时尽可能的容忍供应商的变更,以避免提供多个版本号。
其他
微服务系统多大?
虽然“微服务”一词在架构风格中越来越流行,它的名字非常不辛让人关注它的服务大小,以及对“微”这个组成的争议。在我们与微服务实践者的谈话中。我们发现了服务的大小范围。被报道的最大团队遵循亚马逊Tow Pizaa团队理念(比方,一个团队吃两个比萨就能够了。
),这意味着不超过20号(一打)人。
我们发现最小配置是半打的团队支撑起一打的服务。
这也引发这种考虑:规模为一个服务一打人到一个服务一个人的团队打上微服务的标签。此刻我们觉得,它们是一样的,可是随着对这种风格的深入研究,也存在我们改变我们的想法的可能。
微服务与SOA
当前我们谈到微服务时,一般会问,这是不是我们20年前讨论的面向服务架构(SOA)。这是一个非常好的观点,由于微服务风格也SOA所提倡的一些优势非常相似。虽然如此,问题在于SOA意味的
太多不同的东西了,因此通常时候我们谈的所谓“SOA”时,它与我们谈论的风格不一至,由于它一般是指在总体风格应用中的ESB。
此外,我们发现面向服务的风格是这么的拙劣:从试图使用ESB隐藏复杂性。 到使用多年才认识到发费数百美元却没产生任务价值这种失败。到集中治理模式抑制变更。并且这些问题往往非常难发现。
能够肯定的时,微服务社区中使用的很多的技术都开发人员是从大型机构的整合服务经验中发展来的。
Tolerant Reader模式就是这种一个样例。因为互联网的发展。利用简单的协议这个方案,让它从这些经验传达的出来。这是从已经非常复杂的集中式标准中的一种反模式,坦白的说,真让人惊叹。(不管何时,当你须要用一个服务来管理你的全部的服务,你就知道这非常麻烦。)
SOA的这样的常见行为让微服务的提倡者拒绝打上SOA的标签,虽然有人觉得微服务是从SOA中发展而来的,也许面向服务是对的。
不管怎样,其实SOA表达这么多的含义,它给一个团队清醒的认识到这样的构架风格就已经值的了。
多语言。多选择
JVM做为一个平台。它的增长就是一个平台中执行多语言的最大的样例。
过去二十年中,它通常做为更高层次语言的壳。以达到更高层次的抽象。比方,研究它的内部结构,、使用低级的语言写更高效的代码。虽然如此。很多总体风格并不须要这样的层次的性能优化或者在语法及高层次上的抽象,这非经常见(让我们非常失望)。此外总体构架通常意味着使用单一的语言。这也限制着使用技术的数量。
实践标准和强制标准
它有点尴尬。微服务团队倾向于避免这样的通常由企业架构队伍定制的僵硬的强制标准,可是它们却很乐于甚至推广这些开放的标准,如HTTP、ATOM、其他微规范。
关键的不同在这些标准是怎么开发出来的,以及它们是怎么被推广的。
标准被一些组件管理,如IETF认证标准,仅当它们在互联网上有几个在用的实现。通常源自于开源project的成功应用。
这些标准单独分离出来,与那种在企业中通常有没有什么编码经验的或者没有什么影响力的厂商标准进行差别。
让做对事更easy
一方面,我们发如今持续公布、部署越来越多的使用自己主动化。是非常多实用的工具开发出来帮助开发人员和运营商的努力结果。为打包、代码管理、支撑服务的工具。或者添加标准监控的记录的工具。如今都非经常见了。网络中最好的。可能就是
Netflix‘s的开源工具,可是包括
Dropwizard在内的其他工具也被广泛的使用着。
断路器(circuit breaker)和产品中现有的代码
同步是有害的
任务时候,你在服务间的调用使用同步的方法,都会遇到宕机时间的乘积效应。简单的说,你的系统宕机时间是你系统的单独组件的宕机时间的乘积。你面临的选择使用异步或者管理宕机时间。
在www.guardian.co.uk中,它们在新平台中使用一种简单的规则来实现它:在Netflix中每次用户请求的同步调用。他们又一次设计的平台API都会把它构建成异步的API来运行。
微服务是未来吗?
我们写这篇文章的主要目的在于解释微服务的主要思想和原则。
可是发时间做这事的时候。我们清醒的认识到微服务构架风格是一个很重要的想法:一个值得企业应用中认真考虑的东西。我们近期使用这样的风格构建了几个系统,认识那些也使用和喜欢这样的方法的爱好者。
我们认识的使用这样的方式的先行者,包括亚马逊、Netflix、The Guardian、The UK Government Digital Service、realestate.com.au、Forward和comparethemarket.com。2013看的巡回会议充满了向正在想成为微服务一分子的公司,包括Travis CI。此外,大量的组件正在从事我们觉得是微服务的事,仅仅是没有使用微服务的名字而已。
(通常,它们被打上SOA的标签。虽然。我们觉得SOA有很多不同的地方。)
虽然有这些积极的经验,然后,我们也不急于确认微服务是未来软件架构方向。
至今为止。我们的经验与总体风格的应该中相比出来的是有优势的,可是我们意识知这种事实,我们并没有足够的时间来证明我们的论证。
你所使用的架构一般是你开发出来后。使用的几年的实际成果。
我们看到这些project是在一个优秀的团队,带着对模块化的强烈追求,使用在过去几年中已经衰退的总体架构构建出来的。很多人相信,这样的衰退不太可能与微服务有关,由于服务边界是清晰的而且非常难再完好的。
然而,当我们还没看到足够多的系统执行足够长时间时,我们不能肯定微服务构架是成熟的。
当然,还有原因就是,有人期望微服务构架不够成熟。
在组件化方面的不论什么努力,其成功都依赖于软件怎样拆分成适合的组件。指出组件化的准确边界应该在那,这是很困难的。
改良设计要承认边界的权益困境和因此带来的易于重构的重要性。
可是当你的组件是被远程通信的服务时。重构比进程内的库又要困难的多。服务边界上的代码迁移是困难的,任务接口的变更须要參与者的共同协作,向后兼容的层次须要被添加。測试也变更更加复杂。
还有一个问题在于,假设组件并没有清晰的划分,你的工作的复杂性将从组件内部转向组件间的关系。做这事不仅要环绕着复杂。它也要面对着不清晰和更难控制的地方。非常easy想到。当你在一个小的、简单的组件内找东西。总比在没有关系的混乱的服务间要easy。
最后。团队技能也是重要的因素。新的技术倾向于被掌握很多其它的技能的团队使用。可是掌握多技能的团队中使用的技巧在较少技能的团队中并非必需的。我们发现大量的少技能的团队构建混乱的整合构架。可是它要发时间去证明使用微服务在这样的情况下会发生什么。一个糟糕的团队通常开发糟糕的系统:非常难说,微服务在这样的情况下能否帮助它们。还是破坏它们。
一个理性的争议在于,我们听说,你不应该从微服务构架開始做。最好从总体构架开发,做模块化开发,然后当总体构架出现故障是再把模块化拆分成服务。
(虽然这样的建议不是好主意,由于一个好的进程内接口并非一个好的服务接口。
)
因此我们持这样的慎重的乐观。
到眼下为止,我们还没有足够认识,关于微构架是否能被大范围的推广。我们不能肯定的说。我们要终结什么。可是软件开发的挑战在于你仅仅能在不完整的信息中决定你眼下要处理的问题。