第2章:架构演进之路
从单体到微服务,从集中式到分布式,从单机到集群——这三条演进路线,说白了就是互联网系统从小到大的成长史。我做了十几年架构,亲眼看着很多系统从一台服务器扛所有,变成几百台机器协同工作。今天咱们就聊聊这条路到底怎么走过来的。
2.1 从单体架构到微服务架构
先说说单体架构。你想想看,一个项目刚开始的时候,功能就那么几个,用户也就几百人。把所有代码写在一个工程里,部署在一台机器上,开发、测试、上线一气呵成。我早期带团队时,一个电商系统就是典型的单体——订单、商品、用户、支付全在一个包里,部署时打个WAR包扔到Tomcat里就完事。
但问题很快就来了。用户量一上来,单体架构的短板就暴露了:
- 耦合太紧:改个支付模块,整个系统都得重新部署
- 扩展困难:订单模块压力大,但你不能只给订单加机器,得整个系统一起扩
- 技术栈锁定:Java写的项目,想用Go做某个模块?没门
我记得有一次,双十一大促,订单模块扛不住了,但商品模块其实很闲。我们只能给整个系统加机器,白白浪费了资源。那次之后,我就下定决心要拆。
微服务架构的核心思路:把一个大系统拆成多个小服务,每个服务独立部署、独立扩展、独立技术栈。服务之间通过轻量级通信协议(比如HTTP/REST或gRPC)交互。
微服务的好处很明显:
- 每个服务可以独立开发、测试、部署
- 按需扩展,哪个服务压力大就扩哪个
- 团队可以各自为战,效率高
但也不是没有代价。我见过不少团队,一上来就把系统拆成几十个微服务,结果运维成本暴涨。你想想看,原来一台机器搞定的事,现在要管几十个服务的部署、监控、日志、链路追踪……嗯,这里要注意,微服务不是银弹,业务复杂度不够的时候,单体反而更香。
我的建议:先做单体,等业务复杂度上来了,再按业务边界逐步拆分。别为了微服务而微服务。
2.2 从集中式到分布式
集中式架构,就是所有东西都放在一台机器上。数据库、应用、缓存、文件存储……全挤在一起。早期很多企业级应用就是这么干的,比如银行的核心系统。
但互联网业务不一样。用户量动辄千万级,一台机器根本扛不住。这时候就得走向分布式——把数据和计算分散到多台机器上。
分布式带来的好处:
- 高可用:一台机器挂了,其他机器顶上
- 高扩展:加机器就能提升性能
- 低成本:用一堆普通PC代替一台超级计算机
但分布式也有自己的坑。我曾经在一个项目中,因为分布式事务没处理好,导致订单数据和库存数据不一致,用户付了钱但商品没扣库存……那叫一个惨。后来我们引入了Seata框架,才把问题解决。
避坑指南:分布式系统最大的挑战是数据一致性。CAP理论告诉我们,一致性、可用性、分区容忍性三者不可兼得。实际项目中,我一般选择AP(可用性+分区容忍性),然后通过最终一致性来保证数据正确。
常见的分布式解决方案:
| 问题 | 解决方案 | 我常用的工具 |
|---|---|---|
| 分布式事务 | TCC、Saga、可靠消息 | Seata、RocketMQ |
| 分布式锁 | Redis、ZooKeeper | Redisson、Curator |
| 分布式ID | 雪花算法、UUID | 美团Leaf、百度UidGenerator |
| 分布式配置 | 配置中心 | Nacos、Apollo |
2.3 从单机到集群
单机部署,就是一台机器跑所有服务。用户少的时候没问题,但一旦流量上来,单机就是瓶颈。CPU、内存、磁盘IO、网络带宽,总有一个先扛不住。
集群化,就是把多台机器组合起来,对外表现为一个整体。常见的集群模式有:
- 主从集群:一台主节点负责写,多台从节点负责读。比如MySQL主从、Redis主从
- 对等集群:所有节点地位平等,共同分担请求。比如Nginx负载均衡后面的应用服务器集群
- 分片集群:数据按规则分散到不同节点。比如Redis Cluster、MongoDB Sharding
我印象最深的一次,是给一个社交平台做架构升级。原来单机MySQL扛着所有读写,高峰期CPU直接飙到99%。后来我们做了主从集群,读写分离,主库负责写,从库负责读。效果立竿见影,CPU降到了30%以下。
集群设计的关键点:
- 负载均衡:请求要均匀分发到各节点,避免热点
- 健康检查:节点挂了要自动摘除,恢复后自动加入
- 数据同步:节点之间数据要一致,或者至少最终一致
- 故障转移:主节点挂了,从节点要能自动升为主
举个例子,一个典型的Web集群架构:
用户请求
↓
DNS轮询 / CDN
↓
Nginx负载均衡(多台)
↓
应用服务器集群(多台,无状态)
↓
Redis缓存集群(主从+哨兵)
↓
MySQL数据库集群(主从+分库分表)
这个架构,每一层都是集群。单点故障?不存在的。一台Nginx挂了,其他Nginx顶上。一台应用服务器挂了,请求自动转发到其他机器。Redis主库挂了,哨兵自动选一个新主库。
个人经验:集群不是越多越好。节点太多,网络开销和协调成本会急剧上升。我一般建议,应用服务器集群控制在10-20台以内,数据库集群控制在5-10台以内。超过这个数,就要考虑分片或者多机房了。
2.4 三条路线的交汇
你可能会问,这三条路线是独立的吗?其实不是。它们往往是同时发生的:
- 从单体到微服务,必然伴随着从集中式到分布式
- 从单机到集群,又是分布式系统的具体实现
- 微服务架构天然就是分布式的,每个服务都可以独立集群化
我参与过的一个大型电商项目,就是这三条路线的典型实践:
- 先把单体拆成订单、商品、用户、支付等微服务
- 每个微服务都做集群部署,至少3台起步
- 数据库做读写分离+分库分表,缓存做Redis Cluster
- 引入消息队列(RocketMQ)做异步解耦
- 用Nacos做服务注册与发现,用Sentinel做流量控制
结果呢?系统从支撑10万日活,一路涨到1000万日活,架构基本没动。这就是架构演进的价值——不是一步到位,而是随着业务增长,逐步演进。
最后提醒一句:架构演进没有标准答案。我见过很多团队,业务还没起来,就照着大厂的架构抄,结果把自己搞死了。记住,架构是为业务服务的。业务小的时候,单体+单机就够了。业务大了,再逐步走向微服务+分布式+集群。别为了技术而技术。
好了,这一章就聊到这儿。下一章咱们深入聊聊微服务架构的具体设计,包括服务拆分原则、服务治理、以及我踩过的那些坑。到时候见。