10 月,开发者不可错过的开源大数据大会-2021 WeDataSphere 社区大会深圳站 了解详情
写点什么

究竟是该采用面向服务结构,还是要采用单体结构

Goksu Toprak

2021 年 9 月 28 日

究竟是该采用面向服务结构,还是要采用单体结构

关于采用微服务架构还是单体架构,最近业界有不少相关的讨论。本文作者 Goksu Toprak 分析了两种架构风格的优势和适用场景。


本文最初发表于Station Wagon Full of Tapes网站,经原作者 Goksu Toprak 授权由 InfoQ 中文站翻译分享。


围绕该使用面向服务的架构还是该使用单体架构的讨论已经持续很长时间了。大多数团队确实选择了微服务这条道路,因为这是目前的“行业标准”。但是,单体设计依然有其用途和空间,尤其是在某个想法或产品的早期阶段。

我有幸在这两种方式的代码库中都工作过,而且它们都是很标准的形式。我倾向于采用微服务。我有我的理由,并且会在下面的内容中进行分享。首先,我们来谈一下这两种架构模式。

单体架构


它们已经灭绝了吗?没有,而且它们也不应该灭绝。如果你正在开发的应用的代码库可以分组成为一个包,进行一次性的部署,并且能够在负载均衡器背后进行复制(水平扩展),那么就没有必要引入复杂的微服务设计。


水平扩展


当然,从理论上来讲,单体设计并不意味着无法实现拥有单一责任的服务设计。实际上,因为在单体架构中,所有的模块都很易于访问,随着时间的推移,界限很变得非常模糊,如果需要的话,将系统拆分为更小的部分将会变得越来越难。

根据我的经验,单体架构在早期的迭代中速度会比较快,但是随着时间的推移,变更的迭代速度会变得越来越慢。对于如今的初创公司和小规模团队来讲,这个特点使得单体架构依然是一个很有价值的应用开发方式。

如果业务一切进展顺利的话,现在你需要每秒钟为大量的请求提供服务(因为你的产品有越来越多的客户),准确的说,在要求应用 99.9%的时间都能正常访问的情况下,单体设计的局限性就开始出现了。

Airbnb 必须要经历这样的变化,来自 Airbnb 工程团队的 Jessica Tai 曾经做过名为“大迁移:从单体到面向服务”的演讲。

许多团队在达到某种状态时,都会面临相同模式的问题:

  • 持续部署慢得令人痛苦,因为每个变更都需要构建整个包并重新部署。

  • 缓慢的持续部署导致了缓慢的持续集成,这会导致在每次变更后运行的测试数量不断减少。

  • 曾经的快速代码库变成了一个雷区,即便是微小的变更也是如此,因为工程人员无法知道他们所做的变更的影响是什么。

  • 不可能抽象出特定的服务来管理基础设施,数据库连接、管理以及模式变化都是耦合的。

  • 在部署的时候,无法使用像scratch这样的容器镜像虽然这一条在问题清单上的位置比较靠后,但是考虑到我过去在 Docker 方面的工作,这是我最看重的一点)。

面向服务架构


到目前为止,在本文中,我都将面向服务和微服务视为可互换的术语。我认为它们是一回事儿,但是微服务这个词容易让人们认为每个服务都是微型的,这并不是这种风格的架构的要求。

该结构风格的优势恰好对应着单体架构局限性。这并不是一个巧合。当然,这种风格的设计带来的影响不仅仅是积极的,它们对基础设施设计的要求在增加。分布式系统实现起来并不容易。但是,面向服务架构的优点是多于缺点的:

  • 更快的部署,每次部署之后都会有更高的测试执行率。

  • 蓝-绿更新会很容易(相对来讲),这会限制每个服务的停机时间。

  • 工程师对他们的变更的爆炸半径会更有信心,因为他们知道模块的依赖图。

  • 进行扩展的时候不再局限于添加更多的机器来运行重复的单体应用,而是可以进行垂直扩展。

通过上面列出的每种方式的优点和缺点,有些读者可能已经有了自己的判断。然而,正如我在文章开头所提到的那样,面向服务解锁了单体架构一种无法实现的扩展策略,那就是组织性扩展(organizational scaling)

有个很好的问题就是,当一个产品需要超过数百名工程师来一起工作时,随着接触同一代码库的人员规模的增加,保持所有的组织有信心且灵活地进行创新确实是一个挑战。不要与 mono-repo(指的是将项目的代码放到一个 Git 仓库的做法——译者注)相混淆。mono-repo 并不要求采用单一架构。

在单体架构中,团队经常会被阻塞到代码审查中,因为很容易接触到其他团队拥有的部分代码。任何的代码变更都需要完整的构建,这会造成团队之间相互耦合。如果团队 A 有一个失败的 Selenium 测试,那团队 B 想要部署与之不相关的服务变更,凭什么要被阻止呢?(他们不应如此。)

每个服务由只关注该服务的团队及其消费者所拥有,当涉及到建立一个强大的测试基础设施,以及与指标和日志进行集成时,这种架构方式也会产生更大的影响。团队能够更加自信地部署新的变化,因为他们清楚地设定了边界,一些东西如果出现问题的爆炸半径也能精确测量了,因为团队能够测量一切


面向服务架构


这种类型的架构设计交流的前提一般是以后端软件开发作为目标的。

不过,前端开发“最近”也有一个重大的变化,即前端该如何架构。其核心是,就像微服务一样,它们给出了一个实现组织化扩展的机会。这种变化就是“基于组件的架构”,这种方式随着React已经成为了主流。公司构建自己的设计系统不仅仅是为了提高产品开发的速度,他们也希望能够借此扩展组织,实现更低的耦合。

当我被问到这两种方式该选择哪种时,我一般倾向于回答“视情况而定”,随后我经常会得到一个不满意的表情。尽管如此,在有利于组织规模扩展方面,面向服务架构的优势是不容忽视的。


感谢你阅读“Station Wagon Full of Tapes”。


原文链接:


https://p99th.substack.com/p/microservices-vs-monolith

2021 年 9 月 28 日 11:332525

评论

发布
暂无评论
发现更多内容

Spring Security密码登录流程源码分析

读钓

源码分析 spring security springboot

数据与广告系列二:计算广告和推荐系统

黄崇远@数据虫巢

数据挖掘 大数据 互联网 广告 推荐系统

关于工作的一点总结

Lin

工作思路

鄙视链 & 全栈

伯薇

学习 能力提升 全栈

Kubernetes 资料集合

倪朋飞

学习 Kubernetes 架构模式

谈即时编译优化-以异常堆栈丢失为例

寻筝

音视频会议系统-Janus的安装与布署

音视频专家-李超

音视频 WebRTC

Algorithm week 1: Merge Two Sorted Lists

猫吃小怪兽

算法 链表 ARTS 打卡计划

《陆蓉行为金融学讲义》 - 读后感

石云升

读书笔记 投资 行为金融学 理性 公平

谈谈我的云笔记使用之路

读钓

学习 个人成长 写作

字节跳动:高级人才的五个基本素质

池建强

人才培养

Lucene的Smart CN实现分词、停用词、扩展词

Page

中文分词 lucene 停用词 扩展词 SmartCN

k8s 上运行我们的 springboot 服务之——我们的springboot能够在k8s上运行

柠檬

k8s istio springboot

青春时期的打油诗

Lin

随笔

Tomcat学习分享

Lin

tomcat

编程入门整理

紫枫

读书笔记

从引用聊一聊 Java 垃圾回收

Rayjun

Java 引用 对象

ArrayList 源码分析

读钓

Java 源码分析 jdk源码

ARTS week1

紫枫

ARTS 打卡计划

使用 webpack 搭建一个简单的 React 脚手架

张张张小烦

react.js

谈谈控制感(9):提升控制感排名第一的武器

史方远

职场 心理 成长

leetcode练级-两数之和

幸福三寸日光

算法 LeetCode js

【万字图文-原创】 | 学会Java中的线程池,这一篇也许就够了!

一枝花算不算浪漫

并发编程 jdk源码 线程池

其实,还是让我挺震惊的,程序员的换行率竟然高达 40%

非著名程序员

程序员 程序人生 自我思考

ARTS打卡Week 01

teoking

android WebRTC

宏在C++中的替代解决方案

老王同学

时间管理的本质

史方远

职场 心理 成长

Java 数据持久化系列之JDBC

程序员历小冰

Java JDBC 持久化

Spring Data R2DBC 入门

稻草鸟人

MySQL WebFlux springboot R2DBC

leetcode练级-只出现一次的数字

幸福三寸日光

算法 LeetCode js

修改Tomcat窗口的名称

阡陌r

Java tomcat 踩坑 实施

开源中间件技术学习路线

开源中间件技术学习路线

究竟是该采用面向服务结构,还是要采用单体结构-InfoQ