第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 三条路线的交汇

你可能会问,这三条路线是独立的吗?其实不是。它们往往是同时发生的:

  • 从单体到微服务,必然伴随着从集中式到分布式
  • 从单机到集群,又是分布式系统的具体实现
  • 微服务架构天然就是分布式的,每个服务都可以独立集群化

我参与过的一个大型电商项目,就是这三条路线的典型实践:

  1. 先把单体拆成订单、商品、用户、支付等微服务
  2. 每个微服务都做集群部署,至少3台起步
  3. 数据库做读写分离+分库分表,缓存做Redis Cluster
  4. 引入消息队列(RocketMQ)做异步解耦
  5. 用Nacos做服务注册与发现,用Sentinel做流量控制

结果呢?系统从支撑10万日活,一路涨到1000万日活,架构基本没动。这就是架构演进的价值——不是一步到位,而是随着业务增长,逐步演进。

最后提醒一句:架构演进没有标准答案。我见过很多团队,业务还没起来,就照着大厂的架构抄,结果把自己搞死了。记住,架构是为业务服务的。业务小的时候,单体+单机就够了。业务大了,再逐步走向微服务+分布式+集群。别为了技术而技术。

好了,这一章就聊到这儿。下一章咱们深入聊聊微服务架构的具体设计,包括服务拆分原则、服务治理、以及我踩过的那些坑。到时候见。