ARTICLE / 3 MIN READ
高并发系统从单体到分层的演进路线
用容量模型、流量分层和故障边界拆解一个业务如何从单体应用平稳走向高并发架构。
高并发不是“多加几台机器”这么简单。真正的难点是把请求、状态、数据和故障拆到合适的边界,让每一层都能独立扩展、独立限流、独立降级。
先建立流量分层
一个线上请求通常经过 CDN、网关、应用服务、缓存、消息队列和数据库。每层承担不同职责:
| 层次 | 主要职责 | 常见扩展方式 |
|---|---|---|
| 接入层 | TLS、WAF、静态资源、地理就近 | CDN、边缘缓存 |
| 网关层 | 鉴权、限流、路由、灰度 | 多副本、无状态 |
| 应用层 | 业务编排、校验、事务 | 水平扩容 |
| 缓存层 | 热点数据和短期状态 | 分片、主从、淘汰 |
| 异步层 | 削峰、解耦、重试 | 分区和消费者组 |
| 数据层 | 持久化和查询 | 读写分离、分片 |
拆层的目的不是增加组件,而是让一个局部瓶颈不会拖垮全链路。
三个阶段的演进
第一阶段是单体加缓存。先把静态资源交给 CDN,热点读请求放到 Redis,数据库连接池、慢查询和索引做好,通常就能覆盖早期流量。
第二阶段是读写分离加异步化。把通知、积分、报表等非核心动作放入消息队列,主链路只保留必须同步完成的步骤。读流量使用只读副本,写流量仍由主库负责。
第三阶段才是服务拆分和数据分片。拆分边界应围绕业务能力和数据所有权,而不是按 controller 或表数量切分。每次拆分都要有独立的超时、重试、限流和监控。
一个可落地的请求链路
客户端 -> CDN/WAF -> API 网关
-> 本地缓存 -> Redis
-> 应用服务 -> 消息队列
-> 数据库/搜索/对象存储
同步链路只返回用户当前需要的结果;耗时任务返回任务编号,客户端通过查询或推送获取最终状态。这样可以避免把数据库事务时间和外部依赖时间叠加在一次请求里。
设计时必须回答的问题
- 峰值 QPS 是平均值的多少倍,突发持续多久?
- 哪些数据允许秒级延迟,哪些字段必须强一致?
- 单个租户或热点商品是否可能占用大部分流量?
- 依赖超时后是快速失败、降级,还是进入异步重试?
- 扩容时是否会同时扩大数据库连接数和下游压力?
落地检查清单
- 所有实例不保存本地会话,发布可随时摘流。
- 每个下游调用都有超时、最大重试次数和熔断条件。
- 写接口有业务幂等键,消息消费有去重记录。
- 热点 Key 有过期时间、随机抖动和单飞保护。
- 数据库连接池按数据库承载能力设置,而不是按机器 CPU 设置。
- 压测脚本覆盖正常流量、突发流量和依赖变慢三种场景。
高并发架构的终点不是组件最多,而是在明确的容量和故障边界内,让系统能够预测、扩展和恢复。
GITHUB DISCUSSION
评论与回复
评论保存在 GitHub Discussions,登录 GitHub 后即可参与,发布和回复都在本页完成。
评论区进入视口后自动加载。