译者 | 陈峻
目前,业界最常见的软件范例有:单体(Monolith)和微服务架构两种类型。两者的逻辑结构如下图所示。
通常:
一直以来,我们都沿用且谙熟单体架构,下面,我们先主要来讨论微服务架构的各项优点:
2001年,面对各种应用请求的增加,编码问题突显、开发的延迟、以及服务间的相互依赖性等问题,Amazon逐渐意识到需要从头开始重构其系统,因此它将其单一的应用程序分解成小型的、独立的特定于服务(service-specific)的应用程序,开创了微服务的架构。该架构实现了由一种服务接受订单,另一种服务生成待购买的推荐商品列表,而第三种服务负责提供简单的身份验证服务等模式。正如Martin Fowler早在2015年,针对如何构建实用的软件,所给出的建议那样:“几乎所有成功的微服务案例都是从拆分一个巨型的单体架构开始的。”当然,仅仅根据现代化趋势来选择微服务,不一定是正确的。通常,我们认为如下的应用和代码设计需求,更适合企业选择转向微服务:
上图是Amazon在2008年完成的被称为“死亡之星”的微服务基础设施
企业在从单体架构向微服务架构的迁移过程中,往往会遇到各种技术和组织方面的挑战,因此我们有必要了解与之相伴的各类风险:
可见,由于需要一定的资源投入,微服务架构可能并不总是对初创型或中型企业有利。
正如前文所提到的,从一个单体架构迁移到微服务架构不但繁琐耗时,而且存在着风险。那么,我们怎么能够在迁移之前就认定微服务一定适合本企业呢?《微服务迁移模式》一书的作者--Sam Newman,建议开发人员在动手之前考虑如下三个方面的问题:
下面,我们根据Sam Newman的建议,提出一套分析方法:
企业的应用架构师需要能够找到关联的代码对象,并将它们与系统中的业务功能相匹配。
为了保证在构建和迁移至微服务时,用户的体验不会受到影响,开发团队应邀请用户一起进行业务需求分析,构建详细的业务逻辑和数据流。有时,您可能需要一个专有的平台来扩展微服务的资源,并能够支持自动化的调整。在此方面,您可以使用由云服务提供商托管的无服务器类型的基础设施,例如:google Cloud、Microsoft Azure和Amazon Web Services等。
在迁移的过程中,企业需要团结包括开发人员、质量保证(QA)人员、操作运维人员、以及企业所有者等角色,以微服务为驱动,来创建可以从事设计、构建、部署和维护的服务型团队,并尽量简化不必要的审批流程。杰夫·贝索斯曾说:“我们试图创建一支规模不超过两个比萨饼的队伍。”他称之为“双披萨团队规则”。
下面,我将向您介绍从单体架构迁移到微服务架构的一些值得注意的参考经验。
正确的边界往往是有效的微服务架构的基础。相反,如果边界定义错误,则可能导致在新的微服务中,各项功能被频繁更改,特别是那些提供调用的微服务接口,很可能会在随后的集成测试中持续“浮动”。而且,由于不同微服务出自不同的团队,因此它们会牵扯到团队之间的各种反复协商与较量。
一个典型的域分离的例子源于软件公司Istio。由于前期定义不足,在迁移到微服务后不久,Istio团队便从用户处得到了各种反馈。他们很快地意识到,微服务并非像他们最初想象的那么实用。其主要原因是:所有控制面的服务都是被一股脑部署和使用的,并且共享着相同的管理和安全域。因此,为了大幅降低Istio的操作复杂性,以更少的精力满足业务需求,并能够更容易地开发出服务产品,他们决定从微服务架构回归至单体架构,并按照相关的技术标准来构建单体架构,识别架构中的业务域边界,并使用公共的API作为接口,来予以实施。
在迁移之前,一个由工程师和作用域专家组成的团队,可以通过了解现有的实现方式、依赖关系、以及内部事件等途径,来确定哪些功能组可以作为微服务,提供最大的产品价值;而哪些剩下的功能,则可以酌情保留在单体架构中。
每个微服务都需要有一个数据存储库,这在某种程度上给分离数据的管理增加了难度。由于单个存储系统很容易因为失去同步,而出现不一致性,因此您需要使用能够执行主数据管理(master data management,MDM)的工具。例如,它可以通过检查每个订阅者ID的数据库,及时发现其中是否存在相同的ID。据此,就算某个服务停止了工作,它也能够确保用户数据的安全性。当然,最理想的状况是将数据同时存储在微服务和单体表中。
通常,我们与其在性能良好的微服务中添加、重写一段代码,不如为新的或更改后的代码创建或部署一个新的微服务。据此,我们不但可以简化新代码的测试,而且能够减少现有服务在微服务中出错的可能性。
通过对每个微服务采取单独的构建,我们可以在存储库中,以适当的修订级别获取组件文件。
为了尽量简化,我们最好使用同一种工具,在容器中部署微服务。例如,Docker便是被广为推荐的一种容器标准。
.NETflix(奈飞)
为了能够全天候地运营,Netflix需要一种架构来优化交付速度,并扩展到下一个数据量级。因此,Netflix决定摆脱数据中心里由关系型数据库所带来的,在垂直向扩展时的单点故障,使用NoSQL数据库对数据模型进行非规范化处理。同时,该公司采用了由云服务提供的高度可靠的、可横向扩展的分布式系统,并通过选择AWS作为云服务提供商,获得了大规模且广泛的服务和功能。此外,微服务架构也方便Netflix将系统分成独立的服务,其中包括:存储所有观看节目的服务,负责每月信用卡支付的服务,以及分析观看历史以提供类似电影节目的服务。该公司的全部迁移过程耗时整整七年。
Netflix微服务基础设施的逻辑图
Wix.com
由于Wix.com的应用程序是彼此连接的,因此系统一旦在某个部分出现问题,都会导致整个系统的崩溃。对此,Wix.com开创了新的集成和端到端测试模式,运用JSON/RPC协议,在SpringMVC的基础上,构建了一套微服务框架。通过迁移,它们解决了处理微服务之间的通信、故障与调试等的技术债。
Cloud Elements
Cloud Elements使用诸如Minikube和Docker之类的工具,管理本地和远程运行的服务。由于所有的微服务都在Node.js中,因此他们使用诸如Ava等基于npm的单元测试包,实现了代码测试的全覆盖,以应对业务的指数增长,并根据新增的需求不断迭代其微服务。
Best Buy(百思买)
过去,相互依赖的架构造成了Best Buy在业务部署上的难题。长时间的宕机给其在线业务的维持带来了不小的挑战。开发团队往往需要把新的功能逐个打包,再累计发布。如今,他们通过诸如:Chef和Jenkins等工具,实现了持续集成与部署,并且将数据库迁移到了Riak(一个分布式NoSQL键值数据存储)上。
综上所述,我们是否应该跟上软件架构的趋势,放弃单体架构,投入微服务的怀抱,目前尚无绝对的定论。我的观点是:如果目标项目既没有高负载,又无频繁地与外部服务交互的需求,那么我们便可以选择或维持单体架构;而如果系统必须在大量的负载和服务请求下工作,那么微服务架构会是更好的选择。
我们再来看企业的组织结构层面。如果贵公司只有一个开发团队,那么建议您集中精力构建和维护单体架构;但是如果您有几个IT团队,可以同时开发同一个产品的话,微服务会比较合适一些。
客观而言,微服务架构有利有弊,它只是构建软件的另一种方式。是否应该选择完全取决于应用程序的业务需求。当然,您也可以从一个简单的单体架构开始,随着服务需求的增长,慢慢将应用组件独立出来,并迁移到微服务中。这可能是更为稳妥的应用实践。
原文链接:https://dzone.com/articles/Monolith-vs-microservices-architecture-split-or-no
译者介绍
陈峻 (Julian Chen),51CTO社区编辑,具有十多年的IT项目实施经验,善于对内外部资源与风险实施管控,专注传播网络与信息安全知识与经验;持续以博文、专题和译文等形式,分享前沿技术与新知;经常以线上、线下等方式,开展信息安全类培训与授课。