如何设计一个高并发的系统?

0 阅读3分钟

Gemini_Generated_Image_f4k9j9f4k9j9f4k9.png 这个问题我被问过太多次了。

"怎么设计一个高并发系统?"

面试题也好,实际问题也罢,说复杂能扯一堆架构图,说简单其实就三件事:

能不查数据库就不查,能慢点处理就慢点处理,实在处理不了就多叫点人。


【1】拆分

Gemini_Generated_Image_k8wciok8wciok8wc.png 别把所有鸡蛋放一个篮子里。

电商系统,把订单、支付、库存、用户、评价全写在一个工程里,看似省事,实则埋雷。

评价模块流量一暴增,内存一溢出,整个支付功能跟着瘫痪。拆成独立服务,挂一个不影响其他。

故障隔离,还能单独扩容核心模块,比如双 11 之前把支付服务的集群翻倍。


【2】缓存

Gemini_Generated_Image_c9yljsc9yljsc9yl.png 能不查磁盘就不查磁盘。

Redis、Caffeine 这些内存数据库,读取速度是磁盘的 100 倍以上。

10 万人同时刷新同一个商品详情页,直接打 MySQL,连接数瞬间爆满。

把商品标题、价格、描述丢进 Redis,内存扛得住。

Caffeine:目前性能最强的 Java 本地缓存库,Spring 5 默认缓存支持,算法比 Guava 更高效。


【3】消息队列

Gemini_Generated_Image_85u05485u05485u0.png 不是所有事都要马上做。

用户下单,发短信、送积分,这些操作同步做,响应慢。

订单服务发个消息到 RocketMQ,直接返回成功,短信和积分系统慢慢消费。

这叫异步解耦。

还有削峰填谷。瞬时 1 万个请求,数据库只能扛 2 千。MQ 像个蓄水池,先排队,后端按节奏慢慢处理。


【4】分库分表

Gemini_Generated_Image_y6jjldy6jjldy6jj.png 数据多了要分开。

订单表到千万甚至亿级,查询写入都慢。

垂直拆分,一张 50 个字段的大表拆成两张,减少 I/O。

水平拆分,按 User_ID 取模,订单分布到 10 个库,每个库只管一部分数据,压力分摊。


【5】读写分离

Gemini_Generated_Image_xhyhc6xhyhc6xhyh.png 读多写少,分开干。

社交平台,发帖的人少,看帖的人多。

一个主库(Master)负责写,多个从库(Slave)负责读。主库写完通过 binlog 同步给从库。

用户刷新网页,从多个从库随机挑一个读,查询效率成倍提升。


【6】监控

Gemini_Generated_Image_91atil91atil91at.png 眼睛要盯着。

高并发下,任何细微的错误都会被无限放大。哪个节点"冒烟"了得第一时间知道。

CPU、内存、响应时间(RT)、QPS,这些服务指标要盯着。

下单成功率、支付转换率,这些业务指标也不能放。

Prometheus 监控报警,ELK 日志分析,出了问题能及时熔断降级。


就这么简单。

设计高并发系统,本质上就是:能不查数据库就不查(缓存),能慢点处理就慢点处理(异步),实在处理不了就多叫点人(拆分/扩容)。

但有一点要提醒:这些方案都有代价。缓存带来数据一致性难题,MQ 增加系统复杂度,分库分表让跨库查询变得麻烦。