🍵 1. 并发 ≠ 并行
很多人把「并发」和「并行」混为一谈。用咖啡机做类比,区别一目了然:
图 1:并发是「任务调度」问题,并行是「物理执行」问题
一句话总结:并发是结构问题(如何让多个任务共享资源有序推进);并行是执行问题(如何同时动用更多资源)。高并发系统首先要做好并发设计,再根据预算和场景扩展为并行。
🚀 2. 什么是高并发
「高并发」没有绝对阈值,通常指系统需要在单位时间内处理大量同时到达的请求,并保证可用、正确与可预期响应。
📊 QPS / RPS
每秒查询 / 请求数,衡量吞吐量的核心指标。
⏱️ 响应时间 RT
P50 / P95 / P99,尤其是尾部延迟决定用户体验。
🛡️ 可用性
SLA / SLO,例如 99.9%、99.99% 的可用性要求。
高并发的本质矛盾是:有限的资源 vs 无限的流量。所有设计手段,最终都是围绕「扩容、削峰、缓存、异步、降级、限流」这六个关键词展开。
🏗️ 3. 架构层:先让系统能水平扩展
单机性能总有上限。高并发系统的第一要务是把「垂直扩容」变成「水平扩容」。
🔄 无状态服务
请求不依赖本地内存 / 会话,任何节点都可以被替换,水平扩容才成立。
⚖️ 负载均衡
L4/L7 负载均衡把流量均匀分发到多台实例,避免单点过载。
🗂️ 读写分离
读多写少场景,把读压力分散到从库或副本。
📦 服务拆分
按业务或流量特征拆分微服务,隔离故障域,独立扩缩容。
🌐 CDN / 边缘节点
静态资源与可缓存内容下沉到离用户最近的节点,减少源站压力。
🔀 网关与路由
统一入口负责鉴权、限流、路由、协议转换,把非法请求挡在门外。
常见误区:还没做无状态化就急着加机器,结果会话粘滞、本地缓存不一致,扩容反而放大问题。
💾 4. 缓存层:用空间换时间
缓存是高并发系统里性价比最高的手段。请求金字塔越往上,单位成本越低、响应越快。
图 2:多级缓存金字塔
- 缓存穿透 查询不存在的数据,绕过缓存直接打库。解法:布隆过滤器或缓存空值。
- 缓存击穿 热点 key 突然失效,大量请求并发打库。解法:互斥锁、逻辑过期。
- 缓存雪崩 大量 key 同时过期。解法:随机过期时间、多级缓存、熔断降级。
- 一致性 缓存与数据库数据不一致。解法:Cache Aside、延迟双删、消息驱动。
🗄️ 5. 数据库层:往往是真正的瓶颈
数据库连接数和磁盘 I/O 是系统中最容易成为瓶颈的资源之一。高并发下数据库设计要回答三个问题:怎么读、怎么写、怎么连。
✂️ 读写分离
主库写、从库读,配合 Binlog 同步。注意主从延迟对一致性敏感场景的影响。
🧩 分库分表
按用户ID、时间等维度拆分,分散连接和存储压力,但会引入分布式事务复杂度。
🔍 索引与 SQL 优化
合理的索引、避免全表扫描、减少大事务和慢查询,是成本最低的优化。
🔗 连接池
避免每次请求新建连接;合理设置最小/最大连接数、超时、回收策略。
⚡ 冷热分离 / 归档
把历史数据迁出主库,保证热库体积小、查询快。
📝 批量与异步写
合并小写入、异步刷盘,降低磁盘 I/O 频率。
📨 6. 异步与消息队列:削峰填谷、解耦延时
不是每个请求都需要立即返回结果。把非核心、可延迟的操作改为异步处理,能显著降低同步链路压力。
图 3:同步调用 vs 消息队列异步解耦
使用消息队列时要关注:幂等性、顺序性、消息丢失、重复消费、积压处理、死信队列。
🎚️ 7. 并发控制:限流、熔断与降级
当流量超过系统容量时,必须主动拒绝或保护核心链路,而不是被动崩溃。
🚦 限流 Rate Limiting
令牌桶、漏桶、计数器窗口。限制入口流量,保护后端。
🔒 锁与原子操作
悲观锁、乐观锁、分布式锁。防止竞态条件和超卖。
⚡ 熔断 Circuit Breaker
依赖服务故障时快速失败,避免级联雪崩。
📉 降级 Degradation
关闭非核心功能,优先保证主链路可用。
🧱 隔离舱 Bulkhead
按业务或资源池隔离,避免局部故障扩散。
🔄 重试与幂等
网络抖动时合理重试,配合幂等设计防止重复处理。
🔄 8. 资源与连接池:别让创建成本吃掉吞吐量
线程、连接、内存都是昂贵资源。池化的本质是把「创建-销毁」的开销均摊到多次请求上。
- 线程池 / 协程池:控制并发执行数量,避免上下文切换风暴和 OOM。
- 数据库连接池:HikariCP、Druid 等;设置合理的 core/max、idle timeout、leak detection。
- HTTP 连接池:复用 TCP 连接,减少握手和 TIME_WAIT。
- 内存与 GC:避免大对象、频繁对象分配;关注 young/old GC、逃逸分析。
调参原则:池子不是越大越好。过大的连接池会耗尽数据库;过大的线程池会增加 CPU 调度开销和锁竞争。通常结合压测与监控,找到「吞吐量最大、延迟可接受」的拐点。
🛡️ 9. 稳定性与容错:设计要面向失败
高并发下,任何依赖都可能抖动、超时、故障。系统必须假设「故障是常态」。
⏳ 超时与重试策略
设置连接超时、读取超时;重试要有退避和上限,避免惊群。
🎯 兜底与默认值
依赖失败时返回本地缓存、默认值或简化结果,保证核心流程不中断。
🔥 热点防护
识别单 key 热点,进行本地缓存、散列或限流,避免单点打爆。
🧪 全链路压测
在生产环境模拟真实流量,验证容量上限和降级策略是否生效。
📡 10. 可观测性:没有监控的高并发是盲飞
指标、日志、追踪三位一体,才能快速定位高并发下的瓶颈和故障根因。
- Metrics(指标):QPS、RT、错误率、饱和度(CPU / 内存 / 连接数 / 队列长度)。
- Logging(日志):统一 TraceID,避免日志刷屏;关键路径打印入参、耗时、结果。
- Tracing(追踪):分布式链路追踪,定位跨服务慢点和异常传播。
- Alerting(告警):基于 SLI/SLO 设置阈值,减少误报和漏报。
🗺️ 11. 分层防御全景图
图 4:高并发系统分层防御体系
✅ 12. 高并发设计检查清单
- 服务是否无状态?能否水平扩容?
- 是否配置了接入层限流与网关防护?
- 是否建设了多级缓存并处理了穿透/击穿/雪崩?
- 数据库是否做了索引优化、连接池、读写分离或分库分表?
- 非核心流程是否已异步化或放入消息队列?
- 是否有熔断、降级、隔离、超时、重试策略?
- 线程池 / 连接池大小是否经过压测调优?
- 是否具备 Metrics / Logging / Tracing 可观测能力?
- 是否做过全链路压测并验证了容量上限?
- 关键接口是否做了幂等和热点防护?