您当前的位置:首页 > 电脑百科 > 程序开发 > 架构

拆分还是整合:单体和微服务的技术抉择

时间:2023-11-30 12:36:30  来源:InfoQ  作者:

作者 | Ashley Davis

译者 | 明知山

策划 | 丁晓昀

持续之战:单体架构与微服务

"从许多方面来看,微服务就是一种僵尸架构,另一种拒绝死去的知识传染病菌。这种病菌从 J2EE(远程服务器 Bean,有人记得吗?)的黑暗时代开始,经历了 WS-Deathstar 的胡闹,现在又以微服务和无服务器的形式存在。"

—— David Heinemeier Hansson (来源)

随着亚马逊科技在他们的官博中宣称他们放弃了微服务并回归单体架构,单体架构与微服务之间的战争再次爆发。

你对此有何看法?你是支持微服务还是单体?但我想说的是,这种区分有点虚幻,因为人们争论的只是一种虚构的概念:微服务与单体只是整个故事的一个组成部分。

亚马逊云科技的这篇文章被视为他们(作为微服务的长期支持者)已经回头转向单体架构的证据。

尽管文章的标题明显是为了引起关注,但从内容上看,似乎是关于他们从函数即服务向微服务架构(如果不是比微服务更大的分布式应用程序服务)的转变。

但在我看来,这并不重要。这只能说明,亚马逊云科技的一个团队承认他们尝试的架构在一段时间后不奏效,然后尝试了不同的架构,得到了更好的效果。但这又怎样?这只是好的软件开发应该经历的正常过程。

我们都希望专注于最重要的事情,为我们的客户做正确的事情,在微服务与单体的争论中选边站队只会给我们造成阻碍。有时候,我们需要微服务。有时候,我们需要单体架构。(我还不确定我是否会需要 FaaS——但我保持开放的态度)。大多数情况下,我们需要在两个极端之间找到平衡点。

为什么我们害怕微服务?

当然,与单体相比,微服务更难 —— 我承认这一点。但如果你有了自动化的微服务架构,这个论点就站不住脚了。我曾经使用过的一些无缝集成又容易使用的系统就是拥有良好自动化的微服务。另一方面,我曾经参与的一个最困难的项目是一个古老的大单体,几乎没有自动化。我们的日子不会因为选择了单体而变得轻松。

对微服务的害怕有没有可能是对微服务过度炒作的反噬?是的,微服务已经被过度炒作了。微服务不是灵丹妙药。像所有潜在的解决方案一样,它们并不适用于所有场景。当你使用一种错误的架构来解决某个问题(或更糟糕的是,管理层强制要求使用错误的架构)时,我可以理解你为什么会对这种架构充满厌恶。

是否有一部分害怕是来自微服务早期的日子?十年前,微服务确实使开发变得更加困难。但从那时起,工具和平台已经取得了长足的进步,现在比以往任何时候都更容易进行自动化,给微服务开发带来更加无缝和愉快的体验。

也许,一部分害怕来自对复杂性的感知,我认为这是其中很大的一部分。人们会自然而然地害怕(或至少想要避免)复杂性。我说可感知的复杂性,因为不仅仅是微服务会变得复杂,单体也会 —— 只是时间问题。然而,对于微服务来说,复杂性是公开的,所有人都可以看得到,我们必须早日加以应对。在我的“BootstrApping Microservices”一书中,我称之为将痛苦提前,以便能够在开发过程中更容易、以更低的成本应对复杂性。

不幸的是,在现代软件开发中,我们无法逃避复杂性。我们的应用程序正在变得越来越庞大和复杂 —— 即使是普通的单体架构也注定会变得无比复杂。

在现代的大规模软件开发中,我们无法避免复杂性。我们需要使用工具来帮我们管理复杂性,避免它们阻碍我们的开发过程或压垮我们。

为什么微服务看起来如此困难?

"你必须达到这道门槛才能使用微服务。"

—— Martin Fowler (来源)

构建分布式应用程序(不仅仅是微服务)需要更高的技术熟练度。管理大量的服务意味着我们必须拥有自动化管理工具。为了了解我们的服务在做什么,我们还需要跟踪很多东西。随着服务之间的交互变得越来越多,了解这些信息的困难程度将呈指数级增加。

假设你是一个小团队或在开发一个小项目,在不需要微服务的场景中采用了微服务,或者如果你不愿意付出构建和运行分布式系统所需的技能和技术投入,你就不能指望从中得到良好的体验。

另一个可能的痛点是未能适当地将服务与领域对齐。我曾见过一些微服务应用程序与技术对齐但没有与业务需求对齐,导致存在过多的服务和一个不必要的难以管理的系统。将服务分得太小,不必要地增加了系统的复杂性和难度,这是一个问题。

如果你无法正确地将架构与领域对齐,那么无论使用单体还是微服务,都将遇到严重的问题 —— 随着服务数量的增加,这些问题将会被大幅放大。微服务既能带来性能方面的伸缩性,也会放大已经存在的问题。

这只是一个伸缩性问题吗?

"如果你无法应对单体的复杂性,凭什么认为微服务就是良方?"

—— Simon Brown (来源)

微服务的真正问题是它们只是放大了已经存在的问题吗?

一个糟糕的微服务实现比糟糕的单体架构糟糕 X 倍(X 是你的分布式应用程序中服务的数量)。随着分布式应用程序中通信路径的指数级增加,情况甚至更糟。

如果你没有合适的工具、技术、自动化、流程和组织来应对单体,那么你凭什么认为你可以处理好微服务?

拆分还是整合:单体和微服务的技术抉择

微服务不仅带来性能和开发方面的可伸缩性,也带来了困难程度的伸缩。如果你在构建和维护单体架构时感到困难,转向微服务也并不会给你带来任何好处。

微服务应用程序也是一种单体,只是服务的数量增加了、服务的大小变小了而已。如果疲于应对单体架构,却认为微服务是良方,那么请再三思。

我认为微服务不仅在性能和开发方面带来了可伸缩性,也带来了困难程度的伸缩。微服务有它的优点,但这些优点并不是完全免费的。

微服务的成本

"微服务并非免费午餐。"

—— Sam Newman (摘自“Building Microservices”)

微服务到底是什么?为什么我们要将应用程序划分为独立的服务?

微服务有许多众所周知的好处:

  • 可伸缩性
    • 性能
    • 开发团队
  • 容错性
  • 独立(和较低风险)部署,支持快速开发
  • 开发者赋权
  • 可丢弃(Disposability)
  • 管理复杂性

但这些好处并非微服务的全部,我们也需要为此付出成本:

  • 更高水平的技术技能
  • 更好的自动化、管理和可观察性系统
  • 处理可伸缩性难题

对于任何一种工具、技术、架构或任何我们想要使用的东西,我们必须问自己一个问题:收益是否超过了成本?如果收益超过了成本,你将在使用这些技术时获得良好的体验。如果没有,你将在痛苦的时光中度过。

管理复杂性

"微服务支持大规模、复杂应用的持续部署。"

—— Chris Richardson (来源)

微服务有许多优势,但我们使用它们的真正理由是,它们可以帮助我们管理应用程序日益增长的复杂性。

没错,微服务不是复杂性的根源,而是解决复杂性的方法。

所有的应用程序都将变得复杂,即使是单体也无法避免。微服务为我们提供了将复杂性分解为更小、更简单、更易管理的构建块的工具。

拆分还是整合:单体和微服务的技术抉择

微服务通过将复杂性分解为简单而隔离的部分来帮助我们管理复杂性。我们也可以在单体架构中做到这一点,但你需要一个纪律严明和积极主动的团队来保持设计的完整性,不至于变得一团糟。

我们可以使用微服务来抽象和将软件组件化。当然,我们也可以在单体架构中做到这一点,但微服务还为我们提供了牢固的组件边界,更不用说其他优势了,如独立部署和故障隔离。

可能性频谱

"不存在放之四海而皆准的架构模式。"

—— Dr. Werner Vogels (来源)

我在本文一开始问了一个问题:你是支持微服务还是单体?

回到本文的标题,这不是一个非此即彼的选择。从一个大服务(单体)到许多小服务(微服务),在它们之间还有许多其他可行的选择。

拆分还是整合:单体和微服务的技术抉择

这不只是单体与微服务二选一,它们之间存在一种可能性频谱。如果你将自己固定在支持单体或微服务的立场上,就将错过它们之间丰富的架构多样性。

你不必人为地将自己对准频谱的任意一端。你甚至不必将自己固定在其中任意的特定位置。尽管一些人想让你这样认为,但并不存在所谓的正确的立场。你选择的位置应该与你的团队、业务、项目或客户对齐。只有你可以决定应该处在频谱的哪个位置。

投资回报递减

随着你在频谱的右侧移动,你将获得微服务的好处,但向右移动也伴随着成本和困难的增加。我们需要确保转向微服务的成本是我们愿意承担的。

如果你不是为了管理复杂性,不需要微服务的其他好处,或者在管理单体的自动化和技术方面存在困难,那么你应该尽量留在频谱的左侧。随着你需要微服务的程度的增加,应该朝着频谱的右侧靠近。

拆分还是整合:单体和微服务的技术抉择

随着投资回报递减,一直迈向完美的微服务乌托邦可能是不值得的,但只走其中的一部分道路可能会带来高回报。

此时我们要清楚地认识到,我们不需要达到(我喜欢称之为)微服务乌托邦的程度才能开始享受无服务的好处。无论我们是否达到了频谱的另一侧,我们只要朝着频谱的右侧移动一定程度,都会得到切实的好处!

有很多原因使我们不想迈向完美的微服务。(首先,谁来决定完美的定义?)当我们开始向右侧推进时,将看到巨大的回报。但随着继续向前推进,投资回报开始递减。我们越是朝着更小的服务前进,成本就会超过好处。在杂乱复杂的现实世界中,实现完美的微服务是很困难的,更不用说这其实是不必要的。但这并不意味着朝着那个方向前进不会有所裨益。

混合模型

如果不需要一直推进到微服务一侧,那应该在哪里停下来呢?答案是在中间的某个位置,在这个位置有一些权衡可以提高我们的开发速度和能力,但成本不会超过好处。

我喜欢将在中间的某个位置看作是两全其美。是的,我们可以拥有单体(或多个单体),单体周围环绕着一些微服务。持有这种务实立场的我是否成了某种异教徒?这种架构的实际好处在于我们可以将单体的好处与微服务的好处混合起来。单体代码库的便利性和简单性,加上在必要时可以利用的微服务的灵活性、可伸缩性和其他好处,使得这种架构成为一个理想的选择。如果有必要,我还可以逐步从单体拆分出单独的微服务,让某些功能或任务可以从中受益。

拆分还是整合:单体和微服务的技术抉择

混合模型并不是什么新想法,这就是现实世界通常的样子(在中间的某个位置),尽管人们在网络上继续争论不休。

David Heinemeier Hansson(单体支持者)似乎很喜欢这个想法,他将其称为城堡架构。

大小真的重要吗?

"也许‘Micro’是一个具有误导性的前缀。它并不一定是‘小’的意思。大小实际上并不重要。"

—— Ben Morris (source)

服务越小,就越 Micro,作用就越小,我们就需要越多的服务。随着我们减小服务的大小并增加服务的数量,困难程度也会提升。

或许,我们应该停止专注于微服务“Micro”的部分。我认为这会导致人们将自己的服务变得过于小,而这一定会导致在使用微服务时遇到困难。

我甚至不确定我们是如何如此专注于使它们变得尽可能小的。我们的意图是将软件拆分成不同的部分,分离责任,让每个部分都比整体简单,从而更容易管理系统的复杂性。但如果服务过于小,我们可能会被复杂性淹没,无法管理好它们。

尽管每个人似乎都有自己关于微服务大小的看法,但现实是,微服务的大小没有固定标准。

所以,我们应该停止争论服务的大小,我们应该谈论的是“合适大小”的服务,也就是适合实际情况的适当的大小——单体或者是频谱较小的一端。我们的服务,无论大小如何,都应该根据业务和领域来决定。微服务大小只是后话,整体的组织更为重要。

问题不在于使服务变得尽可能小,服务小到超过某个程度就会适得其反。它们越小,就必须与系统的其余部分进行更多的交互才能完成任务。交互越多,我们就需要付出更高的网络传输成本,更不用说这会使得它们之间的交互变得更加难以理解。我们需要在服务大小和服务有多喋喋不休(Chatty)之间取得良好的平衡(感谢 Damian maclennan 提供了"喋喋不休"一词)。

选择对你来说有意义的服务大小,一些服务比其他服务大,这并不是什么问题。请不要让你的强迫症决定服务的大小——这可能会阻碍一个出色的架构的出现。将服务变得更大或更小本质上没有对错之分,只要你找到适合自己的。

不要害怕改变你的想法

"老实说——我以前也这么做过,从微服务转向单体,然后再转回来。两个方向都有尝试过。"

—— Kelsey Hightower

有时候,为了了解新技术是否适合我们的项目,我们必须进行尝试。所以不要害怕尝试新技术,不要害怕尝试微服务或混合模型,看看它们是否有效。

尝试之后不要害怕改变你的想法,并撤销之前做出的决定。承认某些事情不成功并不是件坏事,这是我们为了取得成功所需要做的事情。尝试不同的事情,进行各种实验,并放弃那些没有成功的事情。因为微服务在特定项目上不适用并不意味着它们对于其他团队或项目也是糟糕的选择。

或者更好的是,保持开放的思维,这是不让自己与新思想和新思维隔绝的最佳方式,这些可能是你做好下一个项目所需要的。

延伸阅读

Bootstrapping Microservices(https://www.bootstrapping-microservices.com/)

Rapid Fullstack Development(https://rapidfullstackdevelopment.com/)

查看英文原文

https://www.infoq.com/articles/monolith-versus-microservices/



Tags:微服务   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  Search: 微服务  点击:(4)  评论:(0)  加入收藏
PHP+Go 开发仿简书,实战高并发高可用微服务架构
来百度APP畅享高清图片//下栽のke:chaoxingit.com/2105/PHP和Go语言结合,可以开发出高效且稳定的仿简书应用。在实现高并发和高可用微服务架构时,我们可以采用一些关键技术。首...【详细内容】
2024-01-14  Search: 微服务  点击:(114)  评论:(0)  加入收藏
九条微服务最佳实践,你学会了哪条?
微服务之间连贯一致的代码库对于可维护性至关重要。保持代码成熟度相似,可确保系统统一演进,防止服务间出现性能、安全性和功能差异。在开发微服务时,我们需要遵循哪些最佳实践...【详细内容】
2024-01-05  Search: 微服务  点击:(97)  评论:(0)  加入收藏
Go微服务入门到容器化实践
Go微服务入门到容器化实践Go 是一门高效、现代化、快速增长的编程语言,非常适合构建 Web 应用程序。而 Docker 是一种轻量级的容器化技术,能够使得您的应用程序在任何地方运行...【详细内容】
2024-01-01  Search: 微服务  点击:(61)  评论:(0)  加入收藏
微服务全做错了!谷歌提出新方法,成本直接降为1/9!
2023,微服务“水逆”之年。长期以来,不管大厂还是小厂,微服务都被认为是云原生服务应用程序架构的事实标准,然而2023,不止那位37signals的DHH决心下云,放弃微服务,就连亚马逊和谷歌...【详细内容】
2023-12-29  Search: 微服务  点击:(117)  评论:(0)  加入收藏
微服务架构中的数据一致性
在微服务中,一个逻辑上原子操作可以经常跨越多个微服务。即使是单片系统也可能使用多个数据库或消息传递解决方案。使用多个独立的数据存储解决方案,如果其中一个分布式流程参...【详细内容】
2023-12-27  Search: 微服务  点击:(141)  评论:(0)  加入收藏
监控 Spring Cloud 微服务的实践方案
一、简介Spring Cloud是一个基于Spring Boot实现的微服务框架,它提供了丰富的微服务功能,如分布式配置、服务注册与发现、服务熔断、负载均衡等。为了更好地管理和监控这样复...【详细内容】
2023-12-19  Search: 微服务  点击:(141)  评论:(0)  加入收藏
聊聊微服务链路服务
微服务架构图片如果有用户反馈某个页面很慢,我们知道这个页面的请求调用链是 A -----> C -----> B -----> D(图片有误),怎么来定位是由哪个服务引起的问题呢? 更进一步,如果...【详细内容】
2023-12-15  Search: 微服务  点击:(123)  评论:(0)  加入收藏
选择适合微服务的编程语言,让你的工作事半功倍!
讨论编程语言就像是一场政治辩论。每个开发者都会过分捍卫他/她所使用的编程语言。然而,编程语言应该被看作是它们真正是的东西,即一种工作工具。每种编程语言都有特定的目的...【详细内容】
2023-12-14  Search: 微服务  点击:(177)  评论:(0)  加入收藏
Eureka: 微服务架构中不可或缺的服务治理工具
Eureka是Netflix开源的一款用于服务治理的工具,它是NetflixOSS(OpenSourceSoftware)项目的一部分,主要用于实现微服务架构中的服务注册与发现。在当今庞大而复杂的微服务系统中,E...【详细内容】
2023-12-14  Search: 微服务  点击:(190)  评论:(0)  加入收藏
▌简易百科推荐
对于微服务架构监控应该遵守的原则
随着软件交付方式的变革,微服务架构的兴起使得软件开发变得更加快速和灵活。在这种情况下,监控系统成为了微服务控制系统的核心组成部分。随着软件的复杂性不断增加,了解系统的...【详细内容】
2024-04-03  步步运维步步坑    Tags:架构   点击:(4)  评论:(0)  加入收藏
大模型应用的 10 种架构模式
作者 | 曹洪伟在塑造新领域的过程中,我们往往依赖于一些经过实践验证的策略、方法和模式。这种观念对于软件工程领域的专业人士来说,已经司空见惯,设计模式已成为程序员们的重...【详细内容】
2024-03-27    InfoQ  Tags:架构模式   点击:(13)  评论:(0)  加入收藏
哈啰云原生架构落地实践
一、弹性伸缩技术实践1.全网容器化后一线研发的使用问题全网容器化后一线研发会面临一系列使用问题,包括时机、容量、效率和成本问题,弹性伸缩是云原生容器化后的必然技术选择...【详细内容】
2024-03-27  哈啰技术  微信公众号  Tags:架构   点击:(10)  评论:(0)  加入收藏
DDD 与 CQRS 才是黄金组合
在日常工作中,你是否也遇到过下面几种情况: 使用一个已有接口进行业务开发,上线后出现严重的性能问题,被老板当众质疑:“你为什么不使用缓存接口,这个接口全部走数据库,这怎么能扛...【详细内容】
2024-03-27  dbaplus社群    Tags:DDD   点击:(11)  评论:(0)  加入收藏
高并发架构设计(三大利器:缓存、限流和降级)
软件系统有三个追求:高性能、高并发、高可用,俗称三高。本篇讨论高并发,从高并发是什么到高并发应对的策略、缓存、限流、降级等。引言1.高并发背景互联网行业迅速发展,用户量剧...【详细内容】
2024-03-13    阿里云开发者  Tags:高并发   点击:(5)  评论:(0)  加入收藏
如何判断架构设计的优劣?
架构设计的基本准则是非常重要的,它们指导着我们如何构建可靠、可维护、可测试的系统。下面是这些准则的转换表达方式:简单即美(KISS):KISS原则的核心思想是保持简单。在设计系统...【详细内容】
2024-02-20  二进制跳动  微信公众号  Tags:架构设计   点击:(36)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  ijunfu  今日头条  Tags:SpringBoot   点击:(8)  评论:(0)  加入收藏
PHP+Go 开发仿简书,实战高并发高可用微服务架构
来百度APP畅享高清图片//下栽のke:chaoxingit.com/2105/PHP和Go语言结合,可以开发出高效且稳定的仿简书应用。在实现高并发和高可用微服务架构时,我们可以采用一些关键技术。首...【详细内容】
2024-01-14  547蓝色星球    Tags:架构   点击:(114)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11    王建立  Tags:Spring Boot   点击:(124)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  互联网架构小马哥    Tags:Spring Boot   点击:(115)  评论:(0)  加入收藏
站内最新
站内热门
站内头条