单体系统时代¶
Monolithic
“单体” 这个名称,却是从微服务开始流行之后,才 “事后追认” 所形成的概念。
思维误区: 单体架构是落后的系统架构风格,最终会被微服务所取代。
备注
进程间通讯:Inter-Process Communication,IPC。RPC 属于 IPC 的一种特例
备注
当我们在讨论单体系统的缺陷的时候,必须基于软件的性能需求超过了单机,软件的开发人员规模明显超过了 “2 Pizza Teams” 范畴的前提下,这样才有讨论的价值。
单体系统:
Monolith means composed all in one piece.
The Monolithic application describes a single-tiered software application
in which different components combined into a single program from a single platform.
—— Monolithic Application,Wikipedia
分层架构(Layered Architecture)
横向扩展(Scale Horizontally)
优点:
易于开发:
开发方式简单,IDE 支持好,方便运行和调试。
功能都在单个程序内部,便于软件设计和开发规划。
易于测试:
所有功能运行在一个进程中,一旦进程启动,便可以进行系统测试。
没有各种复杂的服务调用关系,都是内部调用方便测试。
易于部署:
只需要将打好的一个软件包发布到服务器即可。
程序单一不存在分布式集群的复杂部署环境,降低了部署难度。
易于水平伸缩:
只需要创建一个服务器节点,配置好运行时环境,再将软件包发布到新服务器节点即可运行程序
(当然也需要采取分发策略保证请求能有效地分发到新节点)。
缺点:
维护成本大:
当应用程序的功能越来越多、团队越来越大时,沟通成本、管理成本显著增加。
当出现 bug 时,可能引起 bug 的原因组合越来越多,导致分析、定位和修复的成本增加;
并且在对全局功能缺乏深度理解的情况下,容易在修复 bug 时引入新的 bug。
持续交付周期长:
构建和部署时间会随着功能的增多而增加,任何细微的修改都会触发部署流水线。
新人培养周期长:
新成员了解背景、熟悉业务和配置环境的时间越来越长。
技术选型成本高:
单块架构倾向于采用统一的技术平台或方案来解决所有问题,如果后续想引入新的技术或框架,成本和风险都很大。
可扩展性差:
随着功能的增加,垂直扩展的成本将会越来越大;
而对于水平扩展而言,因为所有代码都运行在同一个进程,没办法做到针对应用程序的部分功能做独立的扩展。
缺点:
1. 单体系统的真正缺陷实际上并不在于要如何拆分,而在于拆分之后,它会存在隔离与自治能力上的欠缺。
2. 在单体架构中,有任一部分代码出现缺陷,过度消耗进程空间内的公共资源,那所造成的影响就是全局性的、难以隔离的
3. 由于隔离能力的缺失,除了会带来难以阻断错误传播、不便于动态更新程序的问题,还会给带来难以技术异构等困难。
4. 单体程序的缺点一开始不是特别明显,项目刚开始需求少,业务逻辑简单,写代码很爽
5. 噩梦从业务迭代更新,系统日益庞大开始,软件维护和迭代更新有无尽的痛苦。
缺点:
1. 系统间通常以 API 的形式互相访问,耦合紧密导致难以维护
2. 各业务领域需要采用相同的技术栈,难以快速应用新技术
3. 对系统的任何修改都必须整个系统一起重新部署 / 升级,运维成本高
4. 在系统负载增加时,难以进行水平扩展
5. 当系统中一处出现问题,会影响整个系统
从开发流程来看主要有以下表现:
1. Git 仓库过于臃肿,代码合并遭遇更多冲突,分支混乱,难以管理
2. Git 仓库臃肿进而导致构建速度变慢,失败频率增加,上线变得困难
3. 臃肿的代码越来越难以理解,维护成本升高,从而需要更多的人力成本
4. 代码之间耦合严重,经常遭遇 “拔出萝卜带出泥” 的窘境,简直让人抓狂
5. 技术栈单一,阻碍技术创新,技术债务堆积
6. 复杂的功能需要消耗更多的资源,导致服务器压力增大,启动速度变慢
7. 由于某些原因引入的一些 bug,可能导致整个系统崩溃,系统稳定性无法满足要求
8. 随着业务增长,服务访问量增加,需要不断增加服务实例数以满足业务增长的需求,无法实现按需扩展
9. 各功能模块之间随意调用,数据可以任意访问,安全性受到很大挑战
从架构角度来看主要有以下表现:
1. 功能模块之间耦合严重,导致代码越来越难以维护和扩展,进而使业务拓展变得困难
2. 团队边界模糊,职责不清晰,一旦出现问题,经常出现互相 “甩锅” 的情况
3. 随着业务的增长,数据库压力与日俱增,数据安全性变差,对数据库的相似操作可能出现在很多服务中
技术异构:
马丁・福勒(Martin Fowler)提出的 9 个特征,技术异构就是其中之一。
它的意思是说允许系统的每个模块,自由选择不一样的程序语言、不一样的编程框架等技术栈去实现。
一个需要权衡的问题:
如果说共享同一进程获得简单、高效这些优势的代价,是损失了各个功能模块的自治、隔离能力,那这两者孰轻孰重呢?
微服务去代替单体系统的根本原因。我认为最根本的原因是:单体系统并不兼容 “Phoenix” 的特性
随着软件架构的不断演进,我们构建可靠系统的观念,开始从 “追求尽量不出错”,转变为了正视 “出错是必然”的。