这个问题我被问过太多次了。
"怎么设计一个高并发系统?"
面试题也好,实际问题也罢,说复杂能扯一堆架构图,说简单其实就三件事:
能不查数据库就不查,能慢点处理就慢点处理,实在处理不了就多叫点人。
【1】拆分
别把所有鸡蛋放一个篮子里。
电商系统,把订单、支付、库存、用户、评价全写在一个工程里,看似省事,实则埋雷。
评价模块流量一暴增,内存一溢出,整个支付功能跟着瘫痪。拆成独立服务,挂一个不影响其他。
故障隔离,还能单独扩容核心模块,比如双 11 之前把支付服务的集群翻倍。
【2】缓存
能不查磁盘就不查磁盘。
Redis、Caffeine 这些内存数据库,读取速度是磁盘的 100 倍以上。
10 万人同时刷新同一个商品详情页,直接打 MySQL,连接数瞬间爆满。
把商品标题、价格、描述丢进 Redis,内存扛得住。
Caffeine:目前性能最强的 Java 本地缓存库,Spring 5 默认缓存支持,算法比 Guava 更高效。
【3】消息队列
不是所有事都要马上做。
用户下单,发短信、送积分,这些操作同步做,响应慢。
订单服务发个消息到 RocketMQ,直接返回成功,短信和积分系统慢慢消费。
这叫异步解耦。
还有削峰填谷。瞬时 1 万个请求,数据库只能扛 2 千。MQ 像个蓄水池,先排队,后端按节奏慢慢处理。
【4】分库分表
数据多了要分开。
订单表到千万甚至亿级,查询写入都慢。
垂直拆分,一张 50 个字段的大表拆成两张,减少 I/O。
水平拆分,按 User_ID 取模,订单分布到 10 个库,每个库只管一部分数据,压力分摊。
【5】读写分离
读多写少,分开干。
社交平台,发帖的人少,看帖的人多。
一个主库(Master)负责写,多个从库(Slave)负责读。主库写完通过 binlog 同步给从库。
用户刷新网页,从多个从库随机挑一个读,查询效率成倍提升。
【6】监控
眼睛要盯着。
高并发下,任何细微的错误都会被无限放大。哪个节点"冒烟"了得第一时间知道。
CPU、内存、响应时间(RT)、QPS,这些服务指标要盯着。
下单成功率、支付转换率,这些业务指标也不能放。
Prometheus 监控报警,ELK 日志分析,出了问题能及时熔断降级。
就这么简单。
设计高并发系统,本质上就是:能不查数据库就不查(缓存),能慢点处理就慢点处理(异步),实在处理不了就多叫点人(拆分/扩容)。
但有一点要提醒:这些方案都有代价。缓存带来数据一致性难题,MQ 增加系统复杂度,分库分表让跨库查询变得麻烦。