高并发详解

总结

高并发就是系统短时间内接收海量请求,核心难点是有限资源对抗瞬时大流量,容易出现性能瓶颈、数据不一致、服务雪崩等问题。

做高并发优化是分层优化的: 前端层做 CDN、资源缓存、请求节流,减少无效请求; 网关层通过 Nginx 做负载均衡、入口限流,分发流量; 应用层保证服务无状态、支持水平扩容,大量热点数据用 Redis 缓存减轻 DB 压力,瞬时大流量通过 MQ 异步削峰、解耦; 数据库层优化 SQL 和索引,采用读写分离、分库分表提升吞吐,优化连接池避免资源耗尽。

同时高并发系统必须配备限流、熔断、降级三大保护机制,防止服务雪崩。 还要解决缓存穿透、击穿、雪崩问题,接口保证幂等性,并发修改资源使用分布式锁保证数据一致。 高并发场景不追求强一致性,一般采用最终一致性换取高性能。

高并发是什么

指系统短时间内大量请求同时访问。

高并发系统设计的核心目标

在有限资源下,尽可能多地处理请求,同时保证系统可用、响应快、数据一致。

高并发核心指

|------------------------------|---------------|---------------------------------|
| 指标 | 含义 | 说明 |
| QPS(Queries Per Second) | 每秒查询数 | 衡量系统每秒能处理多少请求,常用于读场景 |
| TPS(Transactions Per Second) | 每秒事务数 | 衡量系统每秒能完成多少完整业务事务,常用于写场景 |
| RT(Response Time) | 响应时间 | 一个请求从发出到收到响应的时间,通常关注平均、P99、P999 |
| 并发数 | 同时处理的请求数 | 系统同时承载的请求数量,与 QPS 和 RT 相关 |
| 吞吐量(Throughput) | 单位时间处理的数据量 | 可以理解为 QPS/TPS 的上限 |
| 成功率 | 请求成功比例 | 高并发下可能出现超时、失败,需要关注成功率 |
| 资源利用率 | CPU、内存、IO、网络等 | 过高会导致系统不稳定,过低则浪费资源 |

高并发系统到底难在哪里?

最核心的问题其实只有一个:大量请求同时访问有限的系统资源。

高并发带来的核心问题

1.性能瓶颈

  • CPU 计算瓶颈

  • 内存不足

  • 磁盘 IO 瓶颈

  • 网络带宽瓶颈

  • 数据库连接数耗尽

  • 线程/进程资源耗尽

2. 数据一致性问题

  • 超卖:多个请求同时扣减库存,导致库存为负。

  • 脏读、幻读:并发读写导致数据不一致。

  • 缓存与数据库不一致。

3. 可用性问题

  • 单点故障导致整个服务不可用。

  • 线程池满载、连接池耗尽。

  • 雪崩效应:一个服务故障拖垮整个链路。

  • 流量突增导致服务崩溃。

4. 扩展性问题

  • 单机无法通过加配置无限扩展。

  • 数据库单表数据量过大,查询变慢。

  • 应用层无状态化不足,无法水平扩展。

高并发系统设计原则

  • 无状态设计:服务节点不保存用户状态,便于水平扩展。

  • 缓存优先:能缓存的数据尽量缓存,减少数据库压力。

  • 异步处理:非核心逻辑异步化,削峰填谷。

  • 削峰限流:流量入口限流、排队,保护后端。

  • 快速失败:超时、降级、熔断,避免资源被长时间占用。

  • 数据分片:分库分表,分散单库单表压力。

  • 读写分离:主从复制,读多写少时有效。

  • 最终一致性:高并发下不强求强一致,采用最终一致方案。

  • 可监控可观测:实时监控指标,快速定位瓶颈。

  • 容错与冗余:集群部署,避免单点。

高并发解决方案详解

1. 架构层:水平扩展

单体 → 集群

通过负载均衡将请求分发到多个应用节点

应用节点必须无状态,Session 外置到 Redis。

用户请求 → Nginx/LVS → 应用集群(节点1、节点2、节点3...)

微服务拆分

按业务拆分成多个服务,独立部署、独立扩展。

热点服务单独扩容,例如订单服务、库存服务。

前后端分离 + CDN

静态资源(HTML、CSS、JS、图片)放到 CDN,减少源站压力。

动态请求走 API 网关。

2. 负载均衡

|---------|----------------------------------|-----------------------|
| 层级 | 工具 | 说明 |
| 四层负载均衡 | LVS、F5 | 基于 IP+端口,性能高 |
| 七层负载均衡 | Nginx、HAProxy | 基于 HTTP/HTTPS,可做路由、限流 |
| 客户端负载均衡 | Ribbon、Spring Cloud LoadBalancer | 微服务内部调用 |

常用策略:
  • 轮询

  • 加权轮询

  • 最少连接数

  • 一致性哈希(适合有状态缓存)

  • 随机

3. 缓存设计

缓存层级

浏览器缓存 → CDN缓存 → 本地缓存 → 分布式缓存 → 数据库

分布式缓存:Redis / Memcached

Redis 支持丰富数据结构、持久化、集群、事务、Lua。

常见用法:

  • 热点数据缓存

  • 分布式锁

  • 计数器/限流

  • 消息队列(Stream/List)

  • Session 共享

4. 异步与消息队列

为什么异步
  • 同步调用链路长,RT 高。

  • 流量高峰时,同步处理会压垮系统。

  • 非核心逻辑(发短信、日志、积分)可以异步。

消息队列:Kafka / RocketMQ / RabbitMQ
  • 削峰填谷:请求先入队,后端按处理能力消费。

  • 解耦:服务之间不直接调用,通过消息通信。

  • 异步处理:提升主流程响应速度。

示例:秒杀下单

用户下单 → 校验参数 → 发送MQ → 立即返回"排队中"

消费者异步创建订单、扣库存、发通知

5. 限流、降级、熔断

限流

防止系统被突发流量打垮。

|------|------------------------------------------|-----------|
| 算法 | 原理 | 特点 |
| 计数器 | 固定窗口计数(例如 1秒最多1000请求) | 简单,临界问题 |
| 滑动窗口 | 细化时间窗口( 把时间划分成多个小窗口 |100ms|100ms|...) | 更平滑 |
| 漏桶 | 恒定速率流出( 像一个桶: 严格控制输出速度。) | 强制匀速 |
| 令牌桶 | 固定速率放入令牌,请求拿令牌 | 允许一定突发,常用 |

工具:

  • Guava RateLimiter

  • Sentinel

  • Nginx limit_req

  • Redis + Lua 实现分布式限流

降级

当系统压力过大或依赖服务不可用时,关闭非核心功能。

例如:关闭推荐、评论、积分,保留核心下单支付。

熔断

当某个服务错误率超过阈值,自动熔断,快速失败。

熔断器状态:关闭 → 打开 → 半开。

工具:Hystrix、Sentinel、Resilience4j。

6. 数据库高并发优化

读写分离
  • 主库写,从库读。

  • 通过中间件(MyCat、ShardingSphere)或应用层路由。

  • 问题:主从延迟导致读旧数据,可通过强制读主、延迟容忍。

分库分表

当单表数据量过大或写入压力过大时。

|------|--------------------|
| 策略 | 说明 |
| 垂直分库 | 按业务拆分数据库,如用户库、订单库 |
| 垂直分表 | 大表拆小表,常用字段与不常用字段分离 |
| 水平分库 | 数据按规则分散到多个库 |
| 水平分表 | 数据按规则分散到同一库的多个表 |

连接池优化
  • 数据库连接是稀缺资源。

  • 连接池:HikariCP、Druid。

  • 合理设置最大连接数、超时时间。

  • 防止连接泄漏。

SQL 优化
  • 索引优化:覆盖索引、最左前缀、避免索引失效。

  • 避免大事务、长事务。

  • 批量操作合并。

  • 避免 select *。

  • 使用 explain 分析执行计划。

7. 分布式事务

高并发下,强一致性事务(XA)性能差,通常采用最终一致性。

|--------|-------------------------|
| 方案 | 说明 |
| 本地消息表 | 本地事务 + 消息表 + 定时补偿 |
| 事务消息 | RocketMQ 事务消息 |
| TCC | Try-Confirm-Cancel,侵入性强 |
| Saga | 长事务拆分为多个本地事务,失败补偿 |
| 最大努力通知 | 多次尝试,不保证成功 |

8. 分布式锁

在高并发下,防止多个节点同时操作同一资源。

|-------------|------------------------------------|
| 实现 | 特点 |
| 数据库乐观锁 | version 字段,适合冲突不激烈 |
| 数据库悲观锁 | select ... for update,性能差 |
| Redis 分布式锁 | SET NX + 过期时间 + Lua 释放,Redisson 封装 |
| ZooKeeper 锁 | 临时顺序节点,强一致,性能一般 |

注意:

  • 锁粒度尽量小。

  • 设置合理过期时间,防止死锁。

  • 防止误删他人锁(value 唯一标识 + Lua 原子释放)。

  • RedLock 在极端场景下也有争议。

9. 幂等设计

高并发下,网络重试、消息重复消费、用户重复点击都会导致重复请求。

常见方案

  • 唯一业务 ID + 数据库唯一索引

  • Token 机制(前端先获取 token,提交时校验)

  • 状态机控制(订单状态流转)

  • 消息消费端幂等表

  • Redis 去重

10. 监控与压测

监控指标
  • 系统:CPU、内存、磁盘 IO、网络。

  • 应用:QPS、RT、错误率、线程池。

  • 中间件:Redis、MQ、DB 连接数、慢查询。

  • 业务:下单量、支付成功率、库存变化。

压测
  • 工具:JMeter、Gatling、wrk、Locust。

  • 全链路压测:模拟真实流量,发现瓶颈。

  • 关注:QPS 上限、RT 变化、资源利用率、错误率。

一个比较典型的互联网高并发架构

复制代码
     用户

                     │

                     ↓

                 CDN (静态资源分发)/ DNS

                     │

                     ↓

                  Nginx(负载均衡、限流)

              ┌──────┴──────┐

              ↓             ↓

          Spring Boot    Spring Boot

              │             │

              └──────┬──────┘

                     ↓

                   Redis(高性能缓存)

                     │

             ┌───────┴────────┐

             ↓                ↓

    MQ消息队列(异步、削峰)  MySQL(持久化)

                              │

                         主从(读扩展)/分库分表(数据规模)
相关推荐
掘金者阿豪1 小时前
GPT-6 Astra 来了,GPT-5.6 Sol 还值得用吗?聊聊 Coding、百万上下文、价格和 Plus/Pro
前端·后端
SamDeepThinking1 小时前
HashMap 分组操作的演进:从三次查找到一次调用
java·后端·程序员
newerp1 小时前
Golang 接口的两副面孔:eface、iface 与动态派发之谜
后端·程序员·go
万物智能1 小时前
开源鸿蒙内核配置与驱动三条路径—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
前端·后端
Zane19941 小时前
自己写一个 java.lang.String,为什么永远替换不掉 JDK 那个
java·后端
明月_清风2 小时前
递归算法:从原理到实战,一次讲透
后端·算法·go
掘金者阿豪2 小时前
ChatGPT Plus、Pro 5x、Pro 20x 到底有多少额度?聊聊 Codex 那个让人看不懂的“周限额”
后端
用户608186527902 小时前
Avalonia 控件模板实战:从 WPF 迁移自定义 Button 样式的完整指南
后端
Zane19942 小时前
斐波那契数列加个装饰器,速度快了近五千倍:functools 三件套详解
后端·python