第一章:微服务架构演进史:从单体架构到SOA再到微服务,为什么需要微服务?
1.1 那个“一个大项目搞定一切”的年代
我入行那会儿,大概十年前吧,绝大多数企业应用都是单体架构。
什么叫单体?说白了,就是把所有功能——用户管理、订单处理、支付、库存、报表——全部塞进一个代码仓库,编译成一个巨大的WAR包或JAR包,部署到一台服务器上。
你想想看,那时候一个电商系统,前端页面、业务逻辑、数据库访问,全在一个进程里跑。开发团队也就十几个人,大家在一个代码库里改代码,用SVN或者早期的Git管理。听起来挺简单的,对吧?
嗯,确实简单。但问题也出在这个“简单”上。
单体架构的核心特征:
- 所有模块耦合在一起,共享同一个数据库连接池
- 代码库庞大,编译一次要十几分钟甚至更久
- 部署时整个应用一起发布,哪怕只改了一行代码
- 扩展只能垂直扩展(加CPU、加内存),水平扩展成本高
我在项目中遇到过最典型的一个场景:一个支付模块出了Bug,结果整个系统都要回滚。订单模块明明没改,也得跟着重新部署。你说冤不冤?
1.2 单体架构的“三座大山”
随着业务增长,单体架构的问题越来越明显。我个人习惯把这些问题归纳为“三座大山”:
第一座山:开发效率急剧下降
代码量从几万行膨胀到几十万行,甚至上百万行。新同事入职,光看代码就要看两周。改一个功能,可能要影响十几个模块。我记得有一次,一个同事改了一个工具类,结果导致三个模块的单元测试全部失败。为什么?因为那个工具类被到处引用,改的时候没考虑到所有调用方。
第二座山:部署和运维噩梦
单体应用启动就要5分钟,部署一次要半小时。而且,一旦某个模块出现内存泄漏,整个应用都会挂掉。你想想看,支付模块挂了,用户注册功能也用不了——这合理吗?
第三座山:技术栈锁定
单体架构下,你选了一个技术栈,基本就锁死了。比如你用了Spring MVC + MyBatis + MySQL,想换成NoSQL或者引入消息队列?改起来伤筋动骨。我曾经在一个项目里想引入Redis做缓存,结果发现所有模块都直接访问数据库,要改的地方太多了,最后只能放弃。
避坑指南:我曾经见过一个团队,单体应用跑得好好的,非要为了“技术潮流”拆成微服务。结果拆完以后,服务间调用乱成一锅粥,性能反而下降了30%。记住:单体不是原罪,业务复杂度才是。
1.3 SOA:第一次“拆”的尝试
为了解决单体的问题,业界提出了SOA(面向服务架构)。
SOA的核心思想是:把业务功能抽象成服务,通过企业服务总线(ESB)进行通信。每个服务独立部署,独立开发。
听起来和微服务很像,对吧?但实际落地的时候,问题来了。
| 对比维度 | SOA | 微服务 |
|---|---|---|
| 通信方式 | ESB(重量级,通常基于SOAP/XML) | 轻量级API(REST/gRPC,JSON/Protobuf) |
| 服务粒度 | 粗粒度(通常是整个业务域) | 细粒度(一个业务能力一个服务) |
| 数据管理 | 共享数据库 | 每个服务独立数据库 |
| 治理方式 | 中心化(ESB是瓶颈) | 去中心化(服务自治) |
| 部署单元 | WAR包/EAR包 | 独立进程(Docker容器) |
我在项目中接触过SOA的落地。说实话,ESB这个东西,看着很美,用起来很痛苦。它成了单点故障,一旦ESB挂了,所有服务都连不上。而且,SOA的治理太重了,光服务注册和发现就要配置一大堆XML。
1.4 微服务:真正“拆”到极致
2014年左右,Martin Fowler和James Lewis提出了微服务架构的概念。说白了,就是把SOA的“服务”拆得更细,通信更轻量,治理更去中心化。
微服务的核心原则就几条:
- 单一职责:一个服务只做一件事,并且做好
- 独立部署:每个服务可以独立发布,不影响其他服务
- 去中心化治理:每个服务可以选不同的技术栈
- 数据独立:每个服务拥有自己的数据库
为什么需要微服务?说白了,就是业务复杂度到了一定程度,单体架构已经撑不住了。你想想看,一个电商系统,日活从1万涨到100万,单体架构还能扛吗?扛不住的。微服务让你可以针对热点服务单独扩容,比如双十一的时候,只扩容订单服务和支付服务,其他服务保持原样。
1.5 一个真实的演进案例
我记得2017年,我参与过一个传统零售企业的数字化转型项目。他们原来的系统是典型的单体架构,一个Java Web应用,部署在3台服务器上。
业务增长后,问题来了:
- 促销活动期间,系统响应时间从200ms飙升到5s
- 每次上线都要凌晨2点,全团队熬夜
- 一个Bug导致整个系统宕机4小时
我们花了6个月时间,把系统拆成了20多个微服务。拆完之后:
- 促销活动时,只扩容促销服务和订单服务
- 每个服务独立上线,再也不用熬夜了
- 一个服务挂了,其他服务还能正常运转
当然,拆的过程也很痛苦。服务间通信、数据一致性、分布式事务……这些都是新问题。但相比单体架构的“死胡同”,微服务给了我们一条活路。
我的建议:不要为了微服务而微服务。如果你的团队不到20人,业务复杂度不高,单体架构完全够用。微服务是解决复杂问题的工具,不是银弹。
1.6 什么时候该考虑微服务?
我总结了几条判断标准:
- 团队规模:超过20人的开发团队,代码库难以维护
- 业务复杂度:多个业务域耦合严重,改一处影响全局
- 部署频率:每周需要多次发布,但单体部署太慢
- 扩展需求:不同模块的负载差异大,需要独立扩缩容
- 技术多样性:不同模块需要不同的技术栈
嗯,这里要注意:如果以上条件一条都不满足,老老实实用单体。我曾经见过一个只有5个人的团队,硬要拆微服务,结果光搭建基础设施就花了3个月,业务代码一行没写。
1.7 本章小结
从单体到SOA,再到微服务,本质上是一个“拆”的过程。拆的目的是为了应对复杂度,而不是为了炫技。
下一章,我会详细讲微服务拆分的具体原则和方法。到时候我会拿一个真实的电商系统做例子,手把手教你如何把一个大单体拆成合理的微服务。
记住一句话:架构没有银弹,只有权衡。
公众号:蓝海资料掘金营,微信deep3321