高并发系统架构设计
在互联网系统中,“高并发”从来不是稀罕事:双十一秒杀、12306 抢票、新人注册峰值、热点直播点赞…… , 如果你的系统没有良好的架构设计,很容易出现:接口超时、数据错乱、系统宕机。本文从六个核心维度出发,系统性讲解如何构建一套“抗得住流量洪峰”的企业级高并发架构。
一、系统拆分 —— 降低系统耦合度,提高弹性伸缩能力
🧩 核心思想
-
将单体系统按业务域 / 模块 / 职责划分为多个服务;
-
采用微服务架构(如 Spring Cloud / Dubbo);
-
每个服务可以独立部署、扩容、限流、优化;
✅ 实践方式
-
用户、订单、商品、库存分成独立服务;
-
非核心功能(如消息、积分、日志)放入异步服务;
-
使用 API Gateway 做统一入口 + 路由;
⚡ 二、缓存加速 —— 缓解数据库压力,降低响应延迟
🧩 核心思想
-
80%的请求是读取热点数据(如用户、商品详情、排行榜);
-
将这些数据缓存到 Redis/Caffeine,快速读取,减少 DB 压力;
✅ 实践方式
-
Redis 存用户信息、商品详情、配置项;
-
本地缓存 + 分布式缓存结合;
-
设置合理的过期时间 / 热点预加载;
⚠️ 注意
-
保证缓存一致性(缓存穿透、击穿、雪崩问题);
-
使用布隆过滤器、互斥锁、预热策略;
三、MQ异步解耦 / 消峰 —— 降低接口阻塞,解耦系统依赖
🧩 核心思想
-
高频接口中,将非核心任务异步化;
-
请求进队列,慢慢处理,削峰填谷;
-
系统间解耦,失败重试更方便;
✅ 实践方式
-
下单请求入 Kafka,异步处理库存扣减 / 发通知;
-
用户注册时发放优惠券异步处理;
-
秒杀系统通过 MQ 实现异步排队逻辑;
四、数据分离 —— 将冷热数据 / 历史数据分开,提高效率
🧩 核心思想
-
热数据频繁访问,需高性能存储;
-
冷数据只读或不常用,迁出核心库;
-
减轻主库压力,避免表数据膨胀;
✅ 实践方式
-
用户最近 3 个月订单在主库,其它归档库;
-
活跃用户存在 Redis,非活跃查 DB;
-
使用时间分区、归档策略自动搬迁冷数据;
五、读写分离 —— 提升数据库并发处理能力
🧩 核心思想
-
数据库主库负责写,从库负责读;
-
应用按场景将读操作导流至从库,减轻主库压力;
✅ 实践方式
-
MySQL 主从复制 + 读写分离中间件(ShardingSphere、MyCat);
-
读操作通过注解标识自动路由;
-
保证读一致性(强一致 vs 最终一致);
六、服务监控 —— 可观测系统,实时发现瓶颈和故障
🧩 核心思想
-
高并发系统必须实时可监控、可报警、可追踪;
-
否则故障难定位,性能瓶颈无从分析;
✅ 实践方式
-
指标监控:Prometheus + Grafana(QPS、RT、错误率);
-
日志分析:ELK / Loki;
-
链路追踪:Zipkin / Skywalking / OpenTelemetry;
-
报警通知:钉钉 / 飞书 / 企业微信机器人推送;
案例实战:三个典型场景
1. 秒杀抢购系统(如京东618秒杀)
-
高并发瞬间流量
-
使用 Redis 扣库存 + Kafka 异步下单
-
限流(Sentinel)+ 服务隔离 + 防超卖
2. 用户注册高峰(如活动拉新)
-
接口限流 + 验证码防刷
-
Kafka 发放注册礼包异步处理
-
缓存用户状态 + 幂等设计
3. 热点榜单访问(如微博热搜)
-
数据基本不变,访问频率极高
-
Caffeine 本地缓存 + Redis 二级缓存
-
异步定时刷新榜单数据
总结
高并发场景并不可怕,关键在于:
提前设计架构、控制入口流量、解耦核心流程、缓存热点数据、优化数据结构、监控运行状态。
掌握这六大核心手段,能让你的系统 稳如老狗,扛得住打,撑得起业务高峰。
其它例子
12306 抢票系统架构设计
每年春运期间,12306 会在固定时间放票,数以百万计的用户会在同一秒内同时请求抢购有限的火车票。这对系统的并发处理能力、库存一致性、用户体验、数据正确性提出了极高要求。
因此,12306 背后的抢票系统需要具备:
-
高并发承载能力(百万级并发)
-
严格的库存控制(防止超卖)
-
良好的用户体验(快速响应)
-
数据一致性保障(订单唯一、库存准确)
二、整体系统架构
[用户端 App/Web]↓
[CDN + Nginx限流 + 网关]↓
[抢票服务集群 (Java/SpringBoot)]↓
[Redis缓存层] <---> [Kafka队列] <---> [异步下单服务]↓
[MySQL数据库 + 分库分表 + 乐观锁]↓
[订单系统 + 通知系统]
三、架构核心设计点
系统入口限流 + 安全防刷
为防止恶意攻击和机器刷票,需要在系统入口做多重保护:
-
IP / 用户 ID 限流(如每秒最多发起 1 次抢票);
-
接入 验证码 / 滑动验证 等行为识别手段;
-
使用 Nginx / Sentinel / Gateway 限制 QPS;
-
配置 CDN 缓存静态资源,减轻源站压力。
Redis 库存原子扣减,防止超卖
采用 Redis 缓存抢票库存信息,每次抢票前先执行原子扣减操作:
Long stock = redisTemplate.opsForValue().decrement("ticket:train:20250624:G101");
if (stock < 0) {// 票已抢光,回滚库存redisTemplate.opsForValue().increment("ticket:train:20250624:G101");throw new SoldOutException();
}
✅ Redis 的 原子性 和高吞吐能力非常适合处理高并发下的扣库存操作。
Kafka 消息队列:请求削峰 & 异步处理
请求通过 Kafka 进入异步队列,后台服务再逐个生成订单:
-
削峰填谷:避免同时写数据库,打爆 DB;
-
异步解耦:抢票接口只负责入队,立即返回;
-
失败重试机制:Kafka 消息天然具备可持久化能力;
-
可追踪性强:每条消息都是一次完整的订单请求记录。
订单服务异步消费 + 持久化落库
Kafka 消费端负责将已抢成功的请求生成订单,并落入数据库:
@KafkaListener(topics = "ticket-order")
public void handleOrder(OrderMessage msg) {// 1. 校验库存记录(多重保险)// 2. 生成订单号,插入数据库// 3. 设置订单状态为“待支付”
}
💡 同时可以扩展:发送短信、微信通知、设置自动失效机制等。
幂等控制 + 分布式锁防止重复抢票
为防止用户重复提交:
-
使用
SETNX user:train:date
实现幂等锁; -
或使用数据库唯一约束避免插入重复订单;
-
或在 Kafka 消费端做去重(消费前判断 Redis 是否已存在订单记录)。
数据库设计:分库分表 + 乐观锁控制
-
订单、库存表均需 按日期 / 火车号 / 车站等字段分库分表;
-
避免单表数据量超限;
-
使用乐观锁避免并发写入冲突:
UPDATE ticket_stock
SET stock = stock - 1
WHERE train_id = ? AND date = ? AND stock > 0;
四、监控与运维
-
QPS、RT、错误率:通过 Prometheus + Grafana 实时监控;
-
Kafka 消息积压、消费延迟报警;
-
Redis 命中率、内存压力监控;
-
服务健康检查与自动下线机制(避免雪崩效应);
五、系统抗压表现(预估指标)
组件 | 每秒处理能力估计 | 弹性扩展 |
---|---|---|
Redis 扣库存 | 10 万 QPS 以上 | ✅ |
Kafka 入队 | 10 万+ / 秒 | ✅ |
消费服务落库 | 1 万订单 / 秒 | ✅ 可多实例 |
MySQL 写入 | 1000~5000 QPS | ✅ 分库分表 |
六、小结
12306 抢票系统背后,是一套分层解耦、读写分离、异步容错的高并发架构体系。
核心经验总结:
-
限流 + 验证码:入口控制请求;
-
Redis + Kafka:前端控库存,后端异步落库;
-
异步解耦:请求响应快速、降低耦合度;
-
数据库优化:分库分表、唯一索引、乐观锁;
-
监控体系完备:实时可观测,秒级定位问题。