全部文章 笔记与思考

互联网架构演进:从单机到云原生,一篇讲清楚

基于视频《互联网架构就这?1个故事讲清楚》整理并扩展,按业务压力、技术解法和架构代价梳理互联网系统从单机到微服务、云原生的完整演进路径。

互联网架构演进:从单机到云原生,一篇讲清楚

这篇文章基于视频《互联网架构就这?1个故事讲清楚》整理,并加入了一些工程化解释。它不是逐字稿,而是把视频里最有价值的那条线拎出来:架构不是一开始设计出来的,而是业务规模一步步逼出来的。

互联网架构演进封面

很多人学架构时会被一堆名词砸晕:负载均衡、读写分离、缓存、分库分表、RPC、注册中心、消息队列、微服务、Kubernetes……如果只背概念,很容易知道“有什么”,却不知道“为什么会出现”。

更好的理解方式是:把一个网站想象成从 0 开始长大。每次流量变大、数据变多、团队变大,原来的方案就会暴露一个瓶颈。于是架构升级一步,解决一个主要矛盾,同时引入新的复杂度。

从单机到云原生的演进路线图

阶段 当时最痛的问题 典型解法 新代价
单机架构 先把业务跑起来 应用、数据库、文件都放一台机器 扩展能力弱,单点明显
应用与数据分离 应用和数据库抢资源 独立应用服务器与数据库服务器 多一层网络调用
应用集群 单台应用扛不住并发 Nginx / HAProxy + 多应用节点 Session、部署一致性要处理
数据库读写分离 大量读请求压垮主库 主库写、从库读 主从延迟和读一致性问题
多级缓存 热点数据反复打到数据库 浏览器缓存、本地缓存、Redis、CDN 缓存穿透、击穿、雪崩、失效策略
分库分表 单库单表容量和写入到顶 垂直拆库、水平分表 跨库查询、分布式事务、全局 ID
CDN 与反向代理 跨地域访问慢,后端暴露风险高 CDN、Nginx、WAF、SSL 卸载 缓存刷新和边缘一致性
搜索与 NoSQL SQL 不适合全文检索和多变结构 Elasticsearch、MongoDB、HBase 等 多存储同步和数据口径管理
分布式服务 单体越来越难维护和发布 RPC、注册中心、消息队列 服务治理、链路排障、最终一致性
微服务 服务继续膨胀,交付节奏不一致 网关、熔断、限流、追踪、配置中心 运维复杂度显著上升
容器化与云原生 服务太多,人工部署不可控 Docker、Kubernetes、CI/CD、云平台 平台建设和学习成本

核心脉络

架构演进最重要的不是“用了多少技术”,而是每一步都要回答三个问题:

问题 解释
当前瓶颈在哪里? 是 CPU 不够、数据库扛不住、网络太远,还是团队协作卡住了
引入什么组件解决? 负载均衡、缓存、分片、异步消息、服务拆分,各有适用边界
付出的代价是什么? 性能通常是用复杂度换来的,不能只看收益

单机时代的价值是快。一个小网站、一个后台系统、一个 MVP,最开始完全可以用一台机器跑应用和数据库。这个阶段追求的是低成本验证,而不是提前把 Kubernetes、服务网格、消息队列全搬进来。能用简单方案解决的问题,就不要过早分布式。

当流量变大,最先撞到的是资源竞争:应用在吃 CPU 和内存,数据库在吃磁盘 I/O 和缓存,两者混在一台机器上互相拖累。把应用和数据库拆到不同机器,是第一次非常自然的升级。

接下来,应用层通常比数据库层更容易横向扩容。多加几台应用服务器,再用 Nginx 或 HAProxy 做负载均衡,请求就能被分摊出去。这里会遇到第一个“分布式味道”的问题:用户 Session 不能只放在某台应用机器上,否则用户下一次请求被转发到另一台机器时就可能丢状态。

典型读请求链路:从用户到缓存再到数据库

读流量继续增长后,数据库会成为核心瓶颈。多数互联网业务是读多写少,比如浏览商品、看文章、查资料、刷列表。于是主库负责写,从库负责读,读请求可以横向扩展。但这也意味着主从复制存在延迟:刚写完的数据,马上读从库时可能还没同步过去。

缓存是下一次大提速。浏览器缓存减少重复下载,CDN 把静态资源放到离用户更近的边缘节点,本地缓存减少进程外调用,Redis 这类分布式缓存挡住大部分热点读请求。缓存的本质是用空间换时间,但它不是免费午餐:缓存失效、脏数据、热点 Key、穿透和雪崩都需要设计。


数据层怎么长大

数据库的演进可以单独看成一条线:从一台主库,到主从复制,再到分片,再到多种存储协作。

数据层扩展:主从、分片与专用存储

数据问题 常见方案 适合场景
读多写少 主从复制、读写分离 商品详情、文章详情、资料页
热点读 Redis / 本地缓存 / CDN 首页、榜单、用户基础信息
单表太大 水平分表 订单、消息、日志、流水
业务边界清晰 垂直分库 用户库、商品库、订单库、支付库
全文检索 Elasticsearch 商品搜索、站内搜索、日志检索
灵活结构 MongoDB / 文档库 内容、配置、埋点、可变属性
海量写入 HBase / Cassandra / 时序库 监控、IoT、行为日志

分库分表不是“数据库优化的高级形态”,而是单库单表确实扛不住后的手段。它能把数据分散出去,也会带来跨库 Join 难、跨分片事务难、分页统计难、扩容迁移难等问题。

一个比较稳妥的经验是:先优化索引、SQL、缓存和读写分离;只有当数据量、写入量或单表维护成本真的压上来,再进入分库分表。架构升级要被证据推动,而不是被焦虑推动。


从单体到服务化

当系统功能越来越多,单体应用会从“简单”慢慢变成“沉重”。所有模块共用一套代码、一套数据库、一条发布流水线,一个小功能也要跟整个系统一起上线。团队变大后,代码冲突、发布排队、故障影响面都会变得很难受。

服务化的第一步是按业务边界拆开:用户服务、商品服务、订单服务、支付服务、库存服务、推荐服务。拆开之后,每个服务可以独立开发、独立部署、独立扩容。

微服务治理:网关、注册中心、消息队列与可观测性

但服务拆开后,新的问题马上出现:

新问题 需要的能力
服务地址动态变化 注册中心与服务发现
服务之间要高效调用 RPC / HTTP API / gRPC
下游故障会拖垮上游 超时、重试、熔断、降级
高峰写入冲击核心链路 消息队列削峰填谷
一个请求跨很多服务 链路追踪、日志聚合、指标监控
对外入口越来越乱 API 网关、认证、限流、路由

消息队列是服务化里非常关键的一块。它把同步调用变成异步事件,让订单创建、库存扣减、积分发放、短信通知、搜索索引更新等动作不必全部堵在一个请求里完成。代价是系统从“立即一致”变成“最终一致”,业务上要能接受中间状态。

微服务不是单体的反面,也不是架构的终点。它适合业务边界稳定、团队规模较大、部署节奏不同、局部扩容需求明显的系统。如果项目还小,团队也小,强行微服务反而会把工程复杂度提前引爆。


云原生解决的是交付问题

当服务数量来到几十、上百个,真正痛苦的往往不只是代码,而是交付和运维:环境不一致、发布步骤多、机器资源浪费、扩容靠人工、故障恢复慢。

Docker 先把应用和依赖打成标准镜像,解决“在我机器上能跑”的问题。Kubernetes 再把镜像调度到集群里,通过声明式配置维持期望状态:副本少了就补,节点挂了就迁,版本升级按策略滚动。

云原生交付链路:从代码到镜像再到集群

这时架构的关注点从“单个服务怎么写”扩展到“整个平台怎么运行”:

能力 云原生里的对应组件
构建与发布 CI/CD、镜像仓库、GitOps
运行与调度 Docker、containerd、Kubernetes
配置与密钥 ConfigMap、Secret、配置中心
弹性伸缩 HPA、自动扩缩容、弹性云资源
故障恢复 健康检查、自愈、滚动回滚
可观测性 Metrics、Logs、Tracing、告警

云原生并不是“把应用放进容器”这么简单。它更像是一套围绕自动化交付、弹性扩缩容和故障自愈建立起来的平台能力。


常见误区

误区 更合理的理解
一上来就微服务才高级 小系统先单体,等边界和压力清楚后再拆
上了 Redis 就不会慢 缓存命中率、淘汰策略、热点 Key 和回源保护同样重要
分库分表能解决所有数据库问题 它解决容量和吞吐,也会制造查询、事务、迁移复杂度
MQ 能保证绝对一致 MQ 更多是解耦和削峰,常见结果是最终一致
Kubernetes 会自动让系统高可用 K8s 提供平台能力,应用本身仍要处理超时、重试、状态和容量
架构越复杂越厉害 好架构是在当前约束下足够简单、足够可靠、可继续演进

最后可以用一张“什么时候升级”的表来压轴:

你看到的现象 优先考虑
单机 CPU / 内存 / I/O 长期打满 应用与数据库分离,或垂直扩容
应用层 QPS 扛不住 应用集群 + 负载均衡
数据库读压力高 索引优化、读写分离、缓存
热点数据重复查询 多级缓存、CDN
单表过大、写入变慢 分库分表、冷热分离
搜索体验差 Elasticsearch 等搜索引擎
单体发布慢、团队互相阻塞 按业务边界服务化
服务太多、部署混乱 容器化、Kubernetes、CI/CD

总结

互联网架构演进不是一条炫技路线,而是一条不断处理主要矛盾的路线:

1
2
3
4
5
6
先跑起来
  -> 扛住更多请求
  -> 保护数据库
  -> 拆开数据与业务边界
  -> 让服务独立交付
  -> 让平台自动化运行

如果只记一句话:架构升级的本质,是在业务增长带来的新瓶颈面前,用可接受的复杂度换取性能、可用性、可扩展性和交付效率。

真正好的架构师,不是把所有热门技术都塞进系统里,而是知道此刻最应该解决哪个问题,也知道每个方案会带来什么代价。


参考资料