全篇为:从单机架构到负载均衡的互联网架构演进。
从单机架构(程序与数据库部署在同一服务器)开始,指出随着用户增长,会出现资源竞争。
解决方案是将应用与数据库拆分到不同服务器。当单台应用服务器无法承受流量时,引入负载均衡服务器(如 Nginx)将请求平均分发给多台应用服务器,实现水平扩展。
初期单机架构如下图,流量比较小,此时把应用程序与数据库都部署到同一台服务器上。

随着用户量上升,应用程序和数据库开始争夺 CPU、I/O 和内存资源,CPU 和内存被两边抢来抢去,导致整体卡顿。物理分开应用服务器和数据库服务器是分布式架构的初期阶段。

如何解决这一问题?
把它们拆开(物理分离)。分成应用服务器和数据库服务器。
应用服务器:专职处理 HTTP 请求、执行业务逻辑(比如计算价格、校验权限)。
数据库服务器:专职负责磁盘 I/O(读写数据)、执行 SQL 查询。
从单台应用服务器扩展到应用集群

Q&A
为什么要集群?
单台服务器性能有物理上限(CPU、内存、网络带宽);当每秒请求数(QPS)超过单机承载极限时,只能"加机器"------这就是横向扩展(Scale Out)。
集群解决了什么问题?高可用:一台机器宕机,其他机器还能继续服务,不会全站瘫痪。
高并发:5 台机器一起扛流量,总处理能力翻 5 倍(理想情况)。
没有负载均衡器时,虽然有多台服务器,但用户不知道访问哪台,只能靠 DNS 轮询(粗糙且无法屏蔽故障)。
如何解决呢?在所有应用服务器前面架设了一个负载均衡器(Load Balancer,例如 Nginx、HAProxy 或云上的 SLB)。
其中负载均衡有两个主要作用:
流量分发:确保每台应用服务器收到的请求数量大致相等。这样,加机器(即水平扩展)才能真正转化为处理能力的线性提升。
故障自愈 :它会持续检查后面的应用服务器是否存活。如果某台服务器宕机,负载均衡器会立即将其踢出集群,不再分发请求。用户完全感知不到后端有机器坏了------这就是高可用。

那数据库慢了,怎么办?------用空间(内存)换时间(速度)
应用集群能扛住海量请求,但所有请求最终都要去查数据库。数据库的数据在磁盘上,磁盘 I/O 是机械运动,速度比内存慢千倍以上 。既然数据库慢是因为要读磁盘,那就在应用和数据库之间加一道"内存墙"(缓存)。绝大多数读请求直接从内存返回,根本不用经过数据库。
但是又出现了新问题:缓冲区容量有限,无法容纳全部的数据。所以要采用多级缓存方式。
部署到 Redis 上:当前查询所需时间从 ms 级降低到 ns 级。


引入 Redis 缓存,挡住了 80% 的读请求,但又遇到了新的问题:写入操作(增、删、改) 以及缓存未命中的读取 ,依然要穿透到数据库。随着业务量增大,数据库的磁盘 I/O 和锁冲突会越来越严重。那么针对写操作慢和锁竞争问题,对应的解决方案是:读写分离(主从复制),主库负责写,从库负责读,通过数据同步保持一致性。
为解决单表数据量过大(如超 1000 万行)的问题,需要进行分库分表。垂直分库按业务领域(如用户、商品、订单)拆分;水平分表则将一张大表按一致性哈希算法拆成多张小表,配合数据库中间件使用。

垂直分库:
在这张图之前,虽然有主从库,但用户表、商品表、订单表全都挤在同一个物理数据库里)。
痛点 :所有业务的数据挤在一起,某个业务(比如订单)突发大查询,会拖垮整个数据库的CPU和I/O,导致用户登录(查用户表)都变慢。一个业务生病,全家跟着吃药。
解法 :按业务领域(用户、商品、订单)将数据库拆分成独立的数据库实例。每个数据库都有自己的专属主库和从库。
效果 :资源隔离;独立扩展。

引入CDN、反向代理与搜索引擎(Elasticsearch/MongoDB)
支持几十万并发的其他架构组件:CDN用于将静态资源缓存到离用户最近的节点;
反向代理(Nginx)用于隐藏真实服务器、抵御攻击。同时,为应对模糊查询、全文检索等需求,需引入搜索引擎(如Elasticsearch)和NoSQL数据库(如MongoDB)以支持非结构化数据。

但是将所有代码集中在一个巨型工程(巨石应用)会导致维护困难。
解决方案:按业务边界拆分成独立的子系统(如用户、订单、商品集群),形成分布式架构。
进一步地,为追求极致灵活性,可按单一职责将子系统继续拆分为更细的微服务(如登录、会员、支付服务),每个微服务可独立开发、部署和扩容。

以前(单体/分层架构):所有代码(用户、商品、订单)打包在一个大工程里。改一行订单代码,整个项目要重新编译、测试、部署。
现在(微服务拆分) :每个业务(用户、商品、订单)是一个独立的项目、独立的进程、独立部署。每个服务拥有自己独立的数据库(对应你之前做的垂直分库)。
拆分微服务后,用户服务要查订单数据,就不能直接调方法了(因为不在同一个进程里)。跨系统调用可通过RPC实现。RPC(如 Dubbo/gRPC):性能更高,像调本地方法一样调远程服务(二进制传输,序列化更快)。
以前用 Nginx 做负载均衡,IP 是写死在配置文件里的。但在微服务中,服务实例随时会变(扩容、缩容、宕机重启),IP 是动态变化的。
为管理大量服务,需要服务注册与发现中心(如Zookeeper)和消息队列(如Kafka)来实现异步通信、系统解耦和削峰填谷。微服务架构还需引入全链路追踪、限流熔断降级等机制。
为简化部署,使用Docker将应用与环境一起打包,并用Kubernetes(k8s)管理Docker容器。

最后,进行总结:
| 阶段 | 核心动作 | 解决什么问题(学术化表述) |
|---|---|---|
| 1. 单机 | 应用+数据库在一起 | 快速验证与低成本启动:最小化初期基础设施投入,降低部署复杂度,缩短产品上市周期。 |
| 2. 分离 | 应用和数据库拆分 | 消除资源竞用与提升隔离性:通过物理/逻辑隔离,避免应用逻辑与数据存储争抢CPU、内存及I/O资源,保障系统整体吞吐量与稳定性。 |
| 3. 应用集群 | 加多台应用 + Nginx | 引入负载均衡与水平扩展机制:通过横向扩容分摊请求压力,突破单机处理上限,同时实现故障自动剔除,提升系统可用性(HA)。 |
| 4. 缓存 | 引入 Redis | 构建多级缓存体系,降低数据库读压力:利用内存介质的高速读写特性,将热点数据前置缓存,显著降低数据库I/O频次与响应延迟(RT)。 |
| 5. 读写分离 | 主从复制 | 实现读写流量隔离与锁竞争消解:通过主从复制架构,将查询请求分流至从库,消除读写操作间的锁争用,提升数据库并行处理能力。 |
| 6. 垂直分库 | 按业务拆库(用户/商品/订单) | 面向领域的数据物理隔离与故障隔离:按业务边界拆分数据存储,避免跨业务资源争抢,实现故障域的隔离,并为后续服务化拆分奠定数据基础。 |
| 7. 水平分表 | 数据散落到多张表 | 突破单表数据量上限,缓解索引层级退化:通过分片策略将数据打散至多张物理表,降低B+树索引深度,保障数据写入与查询的线性扩展能力。 |
| 8. 多引擎 | 引入 ES、MongoDB | 多模数据存储与专业化查询引擎适配:针对全文检索、半结构化数据、多维分析等场景引入专用存储引擎,弥补传统关系型数据库在非结构化场景下的能力短板。 |
| 9. 微服务 | 拆应用 + RPC + MQ + K8s | 实现组织架构与技术架构的对齐(康威定律):通过服务化拆分降低系统耦合度,引入异步通信与容器编排实现弹性伸缩与故障自愈,支撑大规模协同开发与持续交付(CI/CD)。 |
写入与查询的线性扩展能力。 8. 多引擎 引入 ES、MongoDB 多模数据存储与专业化查询引擎适配 :针对全文检索、半结构化数据、多维分析等场景引入专用存储引擎,弥补传统关系型数据库在非结构化场景下的能力短板。 9. 微服务 拆应用 + RPC + MQ + K8s 实现组织架构与技术架构的对齐(康威定律):通过服务化拆分降低系统耦合度,引入异步通信与容器编排实现弹性伸缩与故障自愈,支撑大规模协同开发与持续交付(CI/CD)。