3、单体架构痛点:部署困难、扩展瓶颈、技术债务积累
好,咱们接着聊。上一章我讲了单体架构的「黄金时代」,那时候一个应用打天下,确实爽。但爽完之后呢?问题就来了。
我记得2015年那会儿,我接手过一个电商系统。代码量大概50万行,部署一次要40分钟。每次上线,团队都像在拆弹。你想想看,一个系统发展到这个地步,痛点已经不是「痒」了,是「疼」。
今天我就把单体架构最要命的三个痛点掰开揉碎讲清楚。分别是:部署困难、扩展瓶颈、技术债务积累。
3.1 部署困难:改一行代码,重启整个系统
这是单体架构最直观的痛。说白了,就是牵一发而动全身。
我举个例子。你有一个电商系统,包含用户、商品、订单、支付、物流五个模块。现在你只想改一下「商品详情页」的文案。按道理,这应该是个小改动。但在单体架构里,你得怎么做?
- 修改代码
- 编译整个项目(50万行代码,编译一次5分钟)
- 打包成WAR包(200MB)
- 上传到服务器
- 停掉Tomcat
- 部署新包
- 重启Tomcat(启动要3分钟)
- 验证所有功能
你看,改一行文案,前后折腾半小时。而且这半小时里,整个系统是不可用的。
核心问题:单体架构的部署粒度是整个应用,不是单个模块。你改任何地方,都得重新部署全部。
我在项目中遇到过更夸张的情况。有一次,运维同事不小心把数据库连接池配置写错了,导致整个应用启动失败。结果呢?所有模块都挂了。用户登录不了,商品看不了,订单下不了。就因为一个配置项,全站瘫痪。
为什么会这样?因为单体架构里,所有模块运行在同一个进程里。一个模块的内存泄漏,可能导致整个进程OOM。一个模块的线程阻塞,可能拖垮整个应用的响应速度。
避坑指南:我曾经见过一个团队,为了「快速上线」,把所有功能都塞进一个WAR包。结果上线后,每次修改都要全量部署。后来他们统计过,平均每次部署耗时1.2小时,其中真正改动的代码不到1%。这就是典型的「为了快,反而慢」。
3.2 扩展瓶颈:不能「指哪打哪」
部署困难是「日常痛」,扩展瓶颈是「成长痛」。系统小的时候不明显,一旦用户量上来,问题就暴露了。
单体架构的扩展方式只有一种:垂直扩展。说白了,就是给服务器加CPU、加内存、加硬盘。但这种方式有天花板。
| 扩展方式 | 单体架构 | 云原生架构 |
|---|---|---|
| 粒度 | 整个应用 | 单个服务 |
| 成本 | 高(升级整台服务器) | 低(只扩展瓶颈服务) |
| 灵活性 | 差(不能按需扩展) | 好(可以精确扩展) |
| 资源利用率 | 低(所有模块共享资源) | 高(按需分配资源) |
你想想看,一个电商系统,平时流量平稳。但双十一来了,订单模块的流量暴增100倍。在单体架构里,你怎么办?
你只能把整个系统都扩展一遍。但问题是,用户模块、商品模块、物流模块,它们并没有那么大的流量。你给它们也配了高配服务器,这就是浪费。
我记得有个朋友的公司,做的是在线教育平台。平时在线人数5000,一到晚上高峰期,在线人数冲到5万。他们的单体应用扛不住,只能把服务器从4核8G升级到16核32G。但问题是,白天流量低的时候,这些资源全浪费了。
更麻烦的是,有些瓶颈是没法通过加机器解决的。比如数据库连接数。单体应用里,所有模块共用同一个数据库连接池。一旦某个模块的查询特别慢,它就会占用大量连接,导致其他模块拿不到连接,整个系统响应变慢。
我的建议:如果你发现系统里某个模块的流量是其他模块的10倍以上,这就是一个强烈的信号——该拆分了。不要等到所有模块都扛不住再动手,那时候成本就高了。
3.3 技术债务积累:越改越乱,越乱越不敢改
这个痛点,做过几年开发的人应该深有体会。单体架构的代码,就像一间住了十年的房子。刚开始装修得挺好,但住久了,东西越来越多,越来越乱。到最后,你连墙都不敢敲,因为你不知道敲掉这面墙,会不会导致天花板塌了。
技术债务是怎么积累的?我总结了几种典型场景:
- 耦合过深:模块之间直接调用,没有接口隔离。改一个模块,要连带改三四个模块。
- 代码臃肿:一个类几千行,一个方法几百行。没人敢重构,因为看不懂。
- 依赖混乱:A依赖B,B依赖C,C又依赖A。形成了循环依赖,改谁都怕。
- 测试缺失:单体应用太大,跑一次全量测试要几个小时。后来大家就不跑了,直接上线。
我在项目中遇到过最典型的例子:一个支付模块,里面混了用户校验、订单查询、物流状态更新。为什么?因为当初开发的时候,为了「省事」,直接在支付方法里调了其他模块的DAO。结果后来需求变了,要改支付流程,结果发现改了支付,订单状态乱了;改了订单,物流通知又出问题了。
这就是技术债务的可怕之处。它不是一天形成的,但一旦积累到一定程度,就会变成「不敢动」的泥潭。
核心观点:技术债务的本质是「短期快感换长期痛苦」。你为了赶进度,写了一段耦合的代码。当时是快了,但后面每次修改都要多花两倍的时间。算总账,其实是亏的。
嗯,这里要注意。技术债务不是不能有,但要有意识地管理。我个人的习惯是:每次新功能上线后,留出20%的时间做重构。哪怕只是抽出一个公共方法,或者拆掉一个循环依赖,都是在还债。
但说实话,在单体架构里,还债的成本很高。因为模块之间耦合太深,你拆一个依赖,可能要改几十个文件。而且没有自动化测试兜底,你根本不敢改。
所以,很多团队的选择是:忍着。忍着忍着,系统就变成了「屎山」。然后新人来了,看不懂,也不敢动,只能继续往上堆代码。最后,系统变得又大又慢又难维护。
这就是为什么我说,单体架构的第三个痛点,其实是最致命的。因为它会慢慢杀死团队的战斗力。
小结
好,这一章的内容就这些。我帮你总结一下:
- 部署困难:改一行代码,重启整个系统。部署时间长,影响范围大。
- 扩展瓶颈:只能垂直扩展,不能按需扩展。资源利用率低,成本高。
- 技术债务积累:耦合深、代码臃肿、依赖混乱。越改越乱,越乱越不敢改。
这三个痛点,其实指向同一个方向:单体架构缺乏「弹性」。它不能灵活地应对变化,无论是业务变化还是流量变化。
下一章,我会讲云原生架构是如何解决这些问题的。说白了,就是「拆」。把一个大系统拆成多个小服务,每个服务独立部署、独立扩展、独立演进。听起来简单,但做起来有很多坑。咱们下章见。
公众号:蓝海资料掘金营,微信deep3321