软件架构 — 微服务架构的三维视角
为何亚马逊不久前会放弃其视频监控系统中的微服务架构(microservices architecture)?
微服务这个概念已经被讨论和仔细考虑了超过15年了。然而,每当你找到一个提供切实建议的资源时,却发现有上千个资源未能给出正确的指导。
在这次深入探讨中,我希望能够让你全面理解微服务,何时使用微服务,并提供工具,以便你可以向业务相关方、开发人员和架构师解释这一切。
了解何时使用微服务和其他架构风格对软件开发人员和工程师非常有帮助,并且对技术/解决方案/软件架构师来说是必不可少的。我在我的解锁软件架构师职业指南中讨论了还有哪些关键内容。
瑞典历史 一个历史 一些历史软件系统进入大众市场始于90年代。虽然个人计算机自70年代就已存在,但随着万维网的出现,90年代真正标志着许多基础的软件开发概念开始成形。在此之前的时段,清晰的架构模式和原则还未被正式定义。
在2000年代初期的某个时候,随着大规模的分布式应用的兴起,人们发现需要更结构化和更好的组织方法。
这导致了分层或“N层”架构风格的出现,其中最著名的是其衍生之一——MVC(模型-视图-控制器)模式。N层架构中,系统被划分为多个物理或逻辑层,每个层包含了表示、业务逻辑和数据访问等功能,并通过清晰定义的输入和输出边界与其他层进行通信。
随着对应用的可扩展性、稳定性和其他架构特性的需求不断增加,新的范式开始浮现。
诸如 空间架构、面向服务的架构(SOA)、基于服务的架构(SBA) 以及 “分层单体架构” 等架构风格变得流行。虽然本文不会详细介绍每一种架构,但值得注意的是,从那时起,一种新的架构风格在行业中开始兴起——基于微服务的架构,这本身就是 SBA 的一种进化。
当时,许多大型企业都在使用面向服务的架构(SOA),而较小的公司大多在构建单体架构。随着对可扩展性的需求增加,即使是小型企业,微服务也变得越来越流行,这促使团队不断提出这样一个核心问题:
“我们应该使用微服务架构还是继续使用单体应用?”
这篇文章要讨论的重点问题就是这个。当然,答案取决于具体的应用场景。我希望能帮助你和你的团队有根据地回答这个问题,提供你们所需的决策工具。
关于独石的故事单体应用就像是一个自给自足的应用程序。它拥有运行所需的一切。嗯,差不多算是吧……通常会有一个外部数据库、缓存 和 消息队列——以及其他类型的组件。
关键是,所有的业务逻辑、API以及与外界的通信都是通过一个系统完成的,该系统很可能作为一个单一的可部署单元来部署。
换句话说,所有业务功能都在同一个地方。历史上,我们就是这么构建应用程序的。一个代码库,一个可部署的单元,团队可以更轻松地理解系统作为一个整体。
MVC(模型-视图-控制器)这种架构在构建单一系统的过程中一直以来都非常受欢迎。
单体怪癖那些事儿单体应用在某些方面确实很美妙,但它同时也带来了一系列限制和挑战。随着时间推移和系统发展,这些挑战会逐渐变得更加明显。
- 随着系统规模和复杂性的增长,系统变得越来越难以维护。
- 理解各个组件的功能变得越来越困难。
- 随着系统复杂性的增加,错误、漏洞和难以察觉的副作用出现的可能性也随之增加。
- 扩展应用规模变得更加有挑战性。
- 系统内部和外部组件之间的相互依赖性增强,使得系统变得更加紧密耦合。
- 随着系统复杂性的增加,新团队成员的入职变得更加困难。
想想看上次你加入一个团队,需要搞清楚他们正在做的一大堆东西。还记得吗?对吧,就是那样……
随着时间的流逝,应用程序会(而且常常是)变成一团乱麻(或者泥潭)。
微服务 — 另一种方式虽然作为一个概念它还是新的,微服务架构为了应对单体应用带来的问题而应运而生。它起源于服务架构的思想。
SBA的理念是,使用多个更细粒度的这样的服务单元,这些服务单元可以各自独立部署,并通过网络互相通信。
微服务是SBA(服务化架构)更明确、更细化和更现代化的版本。在微服务架构下,微服务对“服务”的定义更严格,相比之下,SBA中的服务则更为宽松。
以下是一些高层次的层面的差异:
服务的细粒度基于服务的架构(SBA):更为粗粒度的服务,涉及更广泛的业务领域。
微服务: 细粒度的服务,每个服务都专注于单一职责
服务计数器SBA: 更少但更大的服务
微服务:更小的服务,每个更专注于特定领域
独立日SBA: 服务相对独立,但可能共享资源
微服务定义: 服务彼此高度独立,不共享任何资源
解耦(让它们不再互相依赖)SBA: 较为松散的耦合,但可能会共享数据库或其他依赖项
微服务: 彻底解耦;服务各自负责自己的数据和生命周期
数据处理SBA: 服务可以共用数据库。
微服务: 每个微服务都有自己独立的数据库
开始使用SBA: 服务更经常被一起部署
微服务: 每个微服务都能独立部署
交流SBA: 经常使用同步通信,比如REST。
微服务可以同时使用同步(REST、gRPC)和异步(消息传递)方式。
规模化SBA: 可扩展性仅限于整个服务的扩展
微服务: 可以独立地扩展每个微服务
技术栈SBA: 一般来说,它会是一个统一的技术栈
微服务: 多语言实现——每个微服务都可以使用不同的技术栈
架构演变SBA: SOA的进化,但更简单
微服务:一种更现代、更云原生的分布式系统方法
DevOps 和自动化SBA: 与DevOps没有严格绑定
微服务: 非常依赖于DevOps(开发与运维)和CI/CD流水线(持续集成/持续部署)。
简单来说,以上就是全部了。
_> 一个微服务是一个专门执行特定功能的可部署单元,这个功能是有限的。它通过网络与其他微服务进行通信,并在变更、维护和部署上独立于它们。
不过要再挖深一点吧……
在微服务的上下文中,“Micro”这个词究竟是什么意思?
聊聊什么是“微”,理解微服务出乎意料(或者也许并不意外)——在微服务架构中,一大挑战是定义“微服务”的具体含义。换句话说,需要对每个具体情况进行单独分析,以确定微服务应该承担哪些功能而不应承担哪些功能。
通常来说,一个微服务架构有一个单一职责,具有明确定义的业务和系统边界。
领域驱动设计(DDD)是一种非常有用的框架和方法,特别是在划定业务边界时。
DDD的目标是将技术和业务系统拆解为其基本单元(领域、限定了边界的上下文和子领域)。通过这样做,如此一来,更容易理解整体架构,因此更容易将系统的技术实现与业务功能对应起来。
如果你对领域驱动设计 (DDD) 不太了解,我将在文章末尾为你提供一些不错的资源。
此外,当谈到定义微服务的范围和边界时,定义微服务的职责和边界要么定义得很宽松,要么定义得很严格。
松耦合—— 每个服务都对应一个业务领域或其子领域。例如:用户服务,订单管理,通知。
严格 — 分解为最小的功能单元,每个服务只做一件事。例如,GetUser,PlaceOrder,SendNotification。
实际上,许多组织在使用传统虚拟机或容器应用的情况下更倾向于采取较为宽松的定义。
另一方面,当使用像 AWS Lambda 或 Google Cloud Functions 这样的函数作为服务(FaaS)平台时,通常会将服务划分得尽可能细小。
瑞典中文翻译服务是什麼?改为: 瑞典中文翻译服务是什么?注释部分删除后:
什么是“服务”?最终编辑如下:
什么是“服务”?现在我们已经明白了“微服务”中“微”这个词的含义——接下来我们来看看“服务”这个词。
_> 服务是一个自包含单元,它公开了可以为客户执行的动作。换句话说,服务有明确的输入和输出。
正如我们在文章开头提到的,在过去,我们既有SOA也有SBA。但是,无论是SOA还是SBA,它们的服务都是。
- 粗粒度且范围广泛(有时覆盖整个业务领域)
- 在SOA中,有一个叫ESB的企业服务总线的概念,所有服务通过它进行通信
- 没有定义服务应包含的内容
- 在SBA中,没有明确的服务通信指南
- 缺乏明确的服务重叠、冗余和依赖关系的指导方针
服务的概念在微服务流行之前就已经存在了。然而,它的范围、职责划分和界限并没有像微服务定义得那么清晰。
微服务的优势与挑战: 好处来看看这里的几个好处。
正如我们之前所说,使用微服务架构的好处是显而易见的,具体来说,
- 在架构和服务设计中应用最佳实践:单一职责、高内聚、松耦合
- 功能组织得更好,因此维护更简单且不易出错
- 每个服务可以独立扩展
- 每个服务可以独立部署
- 每个服务可以由不同的团队维护和开发
- 服务的整个生命周期(SDLC)与其他服务独立
- 促进服务的重用
- 更容易理解每个服务
- 减少了特定服务中不必要的和复杂的依赖
与此同时,当你开始使用微服务架构时,你需要考虑几个关键挑战。
- 微服务的范围和边界往往难以定义。定义这些并不总是容易做到。有时,做到完美几乎是不可能的,这会导致系统的重复、责任重叠和各个服务之间的界限模糊。
- 随着部署的服务数量从一个增加到多个,运维模型因此变得更加复杂。你需要部署、监控和调试多个服务。
- 基础设施变得更加复杂。你需要运行多个运行时环境。可能还需要多个数据库。
- 不同的微服务之间存在许多横切关注点。在分布式环境中,监控、审计、安全、事务管理、日志记录等操作会变得更复杂。
- 微服务架构是一个分布式系统。因此,它带来了运行分布式(而非集中式)应用程序的所有挑战,例如网络可靠性(或缺乏)、延迟和传输成本。要更好地理解这些挑战,可以了解一下分布式计算的8大谬误。
- 虽然更容易单独理解每个微服务,但整个服务生态系统却难以理解。你管理的微服务越多,就越可能失去控制。
- 你的团队可能还没有准备好或不具备构建、维护和运行多个服务的经验。团队的结构和能力必须匹配。
- 运行微服务的财务成本可能看起来更高。
说了这么多,接下来我们怎么确保微服务的成功?我们如何防止失败?更重要的是,什么时候该用单体,什么时候该用微服务呢?
这里有一些实用建议。
微服务——如何获胜?- 考虑从模块化单体开始,如有必要再进行拆分。这可以节省时间和精力,并允许在项目初期专注于实际的业务功能。
- 明白你想要解决的问题是什么。
- 从小处开始,一次实现一个模块或微服务。
- 尽可能让每个服务与其他服务独立。松耦合或无耦合才是关键。
- 确保团队和组织结构一致。
- 注意并遵循已有的最佳实践和模式。
- 根据需要演进数据模型——数据库或模型也可能需要拆分。
- 确保操作、监控和支持的一致性。
- 记录架构的细节。
- 构建一个“分布式单体”,这是最糟糕的情况,因为它结合了分布式架构和单体架构的缺点。分布式单体是一种架构,其中你创建了微服务,但它们最终变得相互交织且高度耦合。
- 没有调整团队结构和模型来适应微服务的所有权需求。
- 所有服务都在修改同一个数据库或数据模型中的数据。
- 对你要通过这种架构实现的目标没有明确的概念和蓝图。
- 服务之间的界限不明确,职责也没有清晰界定。
- 没有改进DevOps和CI/CD来支持独立的微服务部署。
- 没有记录架构和服务的细节。
毕竟,每个用例都有其独特性,你也需要考虑到你团队、产品以及组织的具体情况。
不过,有几个原则可以用来判断何时构建这样的微服务架构比较合适。
组织结构有时候,你的团队或组织结构可能需要这样做。换句话说,如果你的团队已经发展壮大,并且已经分成了多个团队,将系统拆分,以反映这种结构,通常是合理的。
不同的非功能需求和架构设计标准当您需要系统中的不同部分具备不同的架构特性和非功能性需求(NFR)时、使用微服务是有意义的。例如:
- 你需要让不同的部分能够独立扩展。例如,你的用户模块每秒接收10个请求,但订单模块需要能够处理每秒大约1000个请求。
- 系统的不同部分有不同的SLA和服务水平目标(SLO)。例如,应用程序的A部分需要亚秒级响应时间的SLA,而B部分的响应时间SLA不得超过200毫秒。
- 不同的安全边界——应用程序的一部分对外公开(例如服务器端渲染的网站),另一部分仅供内部使用,例如审计机制。
当你需要更频繁地部署系统的一部分时,将其拆分出来作为一个独立的微服务这样做是有道理的。
超越微服务的范畴——模块化单体架构,抑或是模独?在过去几年里,业界已经从那些追随微服务潮流的团队,转向了要么放弃微服务,要么对微服务架构变得越来越不信任这两种态度之一。
随着近年来开始实施或已经实施这种架构的许多团队,他们已经开始感受到这种架构带来的成本、复杂性和挑战方面的负面影响。
这已经通过一些流行的用例展示了结果,比如亚马逊放弃了使用微服务架构来进行视频监控。
一种新兴的微服务替代方案是“模块化单体”(Modulith),它旨在将单体和微服务的优点结合起来。
模块化思想是系统作为一个整体部署,但由独立模块组成,这些模块在松耦合、高内聚和粒度上模仿微服务架构的特点。
本质上,modulith 的目标是:
- 依赖自包含模块
- 使用单一部署机制
- 如果需要,轻松拆分为微服务
- 找到微服务架构与单体架构之间的平衡
概述
微服务 在 可扩展性 、 灵活性 和 独立性 方面具有显著优势,但同时也带来了 复杂性 和 运维负担。对于系统或团队规模较小的情况,单体应用 可以是一个很好的起点。模块化单体(也称为 Modulith) 可以提供两者的最佳结合,随着系统的成长,可以轻松地向微服务转变。
要确保微服务的顺利实施,你需要对界限、团队协同和基础设施的准备情况有深刻的理解。最终,选择单体架构还是微服务架构取决于具体的应用场景、团队结构和扩展需求。
在选择哪种架构时,要考虑到架构特性、性能需求以及成本和风险。
最后,在确定任何类型的架构路线图之前,先考虑你想要达成的目标及达成这些目标的最佳途径。分析并记录潜在方案,然后设计解决方案。想一想为什么选择这种架构而不是其他架构。这种规划能澄清很多问题,降低错误决策的风险,并为你指明正确的前进方向。
一个有用的资源列表建筑特点
- 软件架构折中系列:架构特点 (CloudWay Digital 的文章)
- 构建微服务 — 第2版(萨姆·纽曼)
- 什么时候该用微服务(什么时候不该用!)
- https://martinfowler.com/articles/break-monolith-into-microservices.html
强烈推荐一下这些资源
案例分析- “Netflix的微服务:掌控混沌”
- https://thenewstack.io/return-of-the-monolith-amazon-dumps-microservices-for-video-monitoring/ 亚马逊放弃微服务转用单体架构进行视频监控的回归
https://developer.mozilla.org/zh-CN/docs/Glossary/MVC (模型-视图-控制器)
分布式计算的误区掌握像微服务这样的架构风格只是成为成功软件或解决方案架构师之路上的一个环节。
建筑师的角色远不止于技术专长,还包括进行战略性权衡,理解非功能性需求,并在技术与业务之间搭建桥梁。
如果你希望在这个角色中成长并取得卓越成就,我已经准备了一份全面的指南,详细介绍了每个希望成为或已经是架构师的人需要的关键技能、职责和知识领域。
从架构模式到有效的业务沟通,我将揭开你在职业生涯中作为软件架构师所需了解的一切,帮助你游刃有余地发展。
如果你想要成为一名软件/解决方案架构师,或者想学会如何在这个职位上做得出色,请看看这份指南:解锁软件架构师的职业
开启软件架构师的职业生涯
共同学习,写下你的评论
评论加载中...
作者其他优质文章