对系统流量暴涨后的高并发设计思路
应对高并发的核心原则
- 分而治之:拆解系统为独立模块,分别优化(如读写分离、服务拆分)。
- 空间换时间:通过缓存、预加载减少实时计算。
- 异步化:避免阻塞,提升吞吐量(如MQ解耦、批量处理)。
- 冗余与弹性:预留资源缓冲,支持快速扩缩容。
- 防御性设计:假设一切可能失败,提前设计降级、熔断、补偿机制。
一、评估现状与容量基线
- 明确系统架构
- 绘制系统全链路拓扑图(包括服务、中间件、存储、网络依赖)。
- 识别核心路径(如用户下单、支付等关键流程)和非核心路径(如日志上报、统计等)。
- 建立性能基线
- 定义当前系统的关键指标:
- 吞吐量:QPS、TPS(每秒处理请求/事务数)。
- 响应时间:平均/分位延迟(如P99、P999)。
- 资源利用率:CPU、内存、磁盘IO、网络带宽占用率。
- 通过压测工具(如JMeter、Locust)模拟峰值流量,记录系统极限值。
- 容量计算
- 计算单节点处理能力(如单机QPS上限)。
- 推导当前总容量:单机容量 × 节点数 × 冗余系数(如70%)。
- 估算10倍流量下的资源缺口(需扩容的节点数、存储空间等)。
二、识别瓶颈与关键问题
- 分层检查法
- 客户端层:
- 请求是否均匀分发?是否存在热点用户或商户。
- 客户端重试策略是否合理(如无限制重试导致雪崩)。
- 网络层:
- 带宽是否饱和?DNS解析、CDN缓存是否有效。
- TCP连接数是否达到上限(如Nginx的worker_connections)。
- 服务层:
- 是否存在线程池阻塞(如数据库连接池耗尽)。
- GC频率是否激增(Full GC导致服务暂停)。
- 中间件层:
- MQ积压(生产速度 > 消费速度)。
- 缓存击穿/雪崩(如Redis集群响应延迟上升)。
- 存储层:
- 数据库锁竞争(如行锁、表锁)。
- 磁盘IOPS或吞吐量达到瓶颈。
- 工具辅助定位
- APM工具:SkyWalking、Pinpoint追踪慢请求链路。
- 性能分析工具:
- CPU/内存:perf、jstack、Arthas
- 网络:tcpdump、Wireshark
- 日志分析:ELK(Elasticsearch+Logstash+Kibana)定位高频错误。
三、优化策略与优先级
- 水平扩展(Scale Out)
- 无状态服务扩容:直接增加应用节点,通过负载均衡(如Nginx、Kubernetes Service)分流。
- 数据库分片:按业务键(如用户ID、商户ID)或时间分片(如按月分表)。
- 缓存集群扩展:Redis Cluster分片或读写分离(主写从读)。
- 异步化与削峰填谷
- MQ解耦:将同步调用改为异步消息(如订单创建后发MQ,下游异步处理)。
- 批量处理:合并高频小请求(如库存扣减批量提交)。
- 延迟任务:非实时操作(如通知、报表)延迟执行。
- 缓存优化
- 热点数据预加载:基于历史访问模式预热缓存。
- 本地缓存+分布式缓存:使用Caffeine+Redis二级缓存,减少网络开销。
- 缓存防击穿:
- 互斥锁(Redis SETNX)或缓存空值(Null Object)。
- 请求合并(如Hystrix Collapser)。
- 数据库优化
- 读写分离:主库写,从库读(通过ShardingSphere或ProxySQL路由)。
- 索引优化:避免全表扫描,覆盖索引减少回表。
- 冷热分离:归档历史数据至OLAP引擎(如ClickHouse)。
- 连接池调优:调整最大连接数、超时时间(如HikariCP配置)。
- 限流与降级
- 限流策略:
- 计数器算法(简单但临界问题)。
- 漏桶/令牌桶(平滑流量,如Guava RateLimiter)。
- 降级方案:
- 非核心功能降级(如关闭推荐算法)。
- 返回兜底数据(如缓存默认值)。
- 熔断机制:Hystrix或Sentinel监控失败率,触发熔断。
- 弹性伸缩
- Kubernetes HPA:基于CPU/内存或自定义指标(如QPS)自动扩缩容。
- Serverless:无状态服务迁移至云函数(如AWS Lambda),按需计费。
四、可靠性保障
- 幂等性设计
- 唯一键防重:数据库唯一索引或Redis防重Token。
- 乐观锁:版本号控制(如UPDATE ... WHERE version=old_version)。
- 幂等接口:服务端生成唯一ID标识请求(如支付流水号)。
- 数据一致性
- 最终一致性:通过MQ重试+对账补偿(如订单与库存最终一致)。
- 分布式事务:
- 柔性事务:TCC(Try-Confirm-Cancel)、Saga模式。
- 刚性事务:XA协议(依赖数据库支持)。
- 容灾与故障转移
- 多可用区部署:避免单机房故障。
- 数据备份:定期快照(如Redis RDB)、跨区域复制。
- 混沌工程:模拟故障(如节点宕机、网络分区),验证系统自愈能力。
五、验证与持续改进
- 压测验证
- 全链路压测:模拟真实流量(包括缓存穿透、异常请求)。
- 逐步增压:从2倍、5倍到10倍逐步验证,观察系统表现。
- 监控与告警
- 指标监控:Prometheus + Grafana可视化核心指标。
- 日志告警:通过ELK设置阈值告警(如错误日志突增)。
- APM告警:追踪慢接口、异常调用链。
- 迭代优化
- 性能回归测试:每次迭代后对比基线指标。
- 容量规划:根据业务增长预测未来资源需求。
数据倾斜:
数据库:集中将大商户的节点配置进行升级
- 分片策略:
- 复合分片:以商户ID与其他附加因子(时间戳、订单号后缀)组合分片,将大商户数据分散到多个分片
- 范围分片+哈希分片混合:小商户用哈希、大用户可以单独划定范围分片,如按数据ID去分库。
- 动态分片:监控方式识别热点分片后,动态增加子分片(如针对热点建立更多分片),新数据按新规则路由
- 分片后数据查询:
- 简单查询(应用层聚合)、Flink实时或Spark离线预生成聚合结果,存入Redis或ES供查询。(如成交额TOP大盘统计);
- 海量查询:用Presto或者Trino这类高并发数据分析引擎建立分片虚拟表,通过sql查询分片并聚合。
- 大商户数据变更,用CDC工具监听分片,全量数据同步到ES,用ES查询。
- 读写分离:热点分片配置多个只读副本,查询路由从库
- 冷热分离:按时间或访问频率拆分数据,热数据留在高性能分片,冷数据归档。Canal同步冷数据到归档库 + Flink(数据迁移)
缓存:
- 多级缓存:高频商户信息本地缓存、完整数据Redis缓存。每日预测TOP商户信息提前加载,避免瞬时冲击;每日凌晨用Spark离线任务计算TOP商户,提前加载到缓存
- 热点探测和染色:用Redis统计商户请求量,识别突然热点,自动打标签并优先缓存。HyperLogLog+Sentinel
业务层优化:
- 热点写请求用MQ削峰,大商户单独队列;分片压力大时,非核心的查询可以考虑简化返回结果,减少查询量
- 超大商户还可以按业务线拆分,避免单表膨胀
架构:
分布式数据库代替分库分表:采用TiDB这种支持自动分片再平衡的数据库
CQRS模式:读写分离,读库用ES加速
弹性扩缩容:做好服务监控,云数据库支持自动扩容,分片压力大时自动增加节点。
本文来自博客园,作者:难得,转载请注明原文链接:https://www.cnblogs.com/zhangbLearn/p/18829296

浙公网安备 33010602011771号