高并发到底是什么?从 QPS、并发数到响应时间

什么才叫高并发?

很多时候我们会看到:

支持 1000 并发
支持 10000 QPS
支持百万级并发

这些数字看起来很直观,但实际上:

1000 并发
1000 QPS
1000 个连接
1000 TPS

完全不是同一个概念。

如果不区分这些指标,就很容易在性能测试和系统设计中得出错误结论。


1. “高并发”到底是什么意思?

“高并发”并不是一个严格固定的数字。

例如:

1000 QPS

对于一个简单的内部管理系统,可能已经非常高。

但对于大型互联网服务,这个数字可能非常普通。

因此:

高并发是相对于系统规模、业务模型和资源能力而言的概念,而不是一个固定阈值。

更准确地说,高并发关注的是:

大量请求
    ↓
在较短时间内
    ↓
同时进入系统
    ↓
系统仍然能够稳定处理

这里至少涉及三个维度:

请求到达速度
请求同时存在的数量
请求完成速度

对应到性能指标,就是:

QPS / RPS
并发数
响应时间 / 吞吐量

因此,讨论高并发时,不能只说:

“我们的系统能扛 10 万并发。”

还应该继续问:

什么类型的请求?
多少 QPS?
平均 RT 多少?
P99 多少?
请求是否访问 MySQL?
数据库连接池多大?
CPU 利用率多少?
内存多少?

否则这个“10 万并发”几乎没有实际意义。


2. 并发数:现在有多少请求正在进行?

并发数(Concurrency)描述的是:

某个时间点或者某个时间窗口内,同时处于处理过程中的任务数量。

例如:

14:00:00
    ↓
请求 A
请求 B
请求 C
请求 D

此时如果这 4 个请求都还没有完成:

Concurrency ≈ 4

需要注意:

并发数不是每秒请求数量。

例如:

系统当前有 100 个请求正在处理

表示:

Concurrency = 100

而不是:

QPS = 100

一个简单例子

假设:

每秒进入 100 个请求
每个请求平均处理 1 秒

那么系统中大约会同时存在:

100 个请求

因此:

Concurrency ≈ 100

如果请求平均只需要:

100ms

那么:

每秒 100 个请求
平均 RT = 100ms

系统中的平均在途请求数量大约是:

100 × 0.1 = 10

也就是说:

QPS = 100
RT = 100ms
Concurrency ≈ 10

这已经说明:

QPS 和并发数不是一回事。


3. QPS 和 RPS:每秒处理多少请求?

QPS 是:

Queries Per Second

传统上经常用于描述每秒处理的查询数量。

对于 HTTP 服务,更准确、也更常见的指标之一是:

RPS(Requests Per Second)

即:

每秒处理多少个请求

例如:

RPS = 1000

可以理解为:

平均每秒完成约 1000 个请求

在 API 服务中:

GET /api/users
POST /api/orders
GET /api/products

都可以按照请求完成数量进行统计。


QPS 不是固定的“系统性能”

假设:

服务器 A
QPS = 1000

服务器 B:

QPS = 2000

不能直接得出:

B 比 A 快一倍

因为还缺少很多信息:

请求内容
CPU
内存
数据库
缓存命中率
响应大小
RT
错误率
P99

例如:

A:
1000 QPS
RT = 10ms

B:
2000 QPS
RT = 5s

如果只看 QPS,B 更高。

但从用户体验和系统稳定性来看,B 未必更好。

所以性能测试一定不能只看 QPS。


4. TPS:它和 QPS 有什么区别?

TPS 是:

Transactions Per Second

即:

每秒完成多少个事务

它更多用于具有明确“事务”概念的场景。

例如:

支付
订单
数据库事务
金融交易

假设一次用户下单操作:

创建订单
    ↓
扣库存
    ↓
创建支付记录

如果整个过程被业务定义为一个 Transaction,那么:

TPS = 每秒完成的交易数量

而 QPS/RPS 更偏向:

Query / Request

因此:

QPS ≠ TPS

两者的具体含义取决于系统的统计口径。

例如一个订单交易可能涉及:

1 个 HTTP 请求
    ↓
5 次 SQL
    ↓
2 次 Redis 操作
    ↓
1 次 RPC

那么:

HTTP RPS = 1000

并不意味着:

SQL QPS = 1000
Redis QPS = 1000
RPC QPS = 1000

真实系统中,一个上游请求可能放大成多个下游操作。

这个问题在下一篇“HTTP 请求的并发链路”中会重点讨论。


5. 响应时间 RT:请求到底花了多久?

RT(Response Time)表示一次请求从开始到完成所经历的时间。

例如:

Request
   ↓
开始:10:00:00.000
   ↓
完成:10:00:00.100

那么:

RT = 100ms

但生产环境不能只看平均 RT。

例如 1000 个请求:

990 个:10ms
10 个:5s

平均值可能仍然不算特别夸张。

但这 10 个用户已经明显感受到卡顿。

因此实际监控中经常关注:

P50
P90
P95
P99
P999

这些称为百分位延迟(Percentile Latency)。

例如:

P50 = 20ms
P95 = 80ms
P99 = 500ms

可以理解为:

50% 的请求 ≤ 20ms
95% 的请求 ≤ 80ms
99% 的请求 ≤ 500ms

这里的统计必须建立在明确的采样窗口和指标口径上。

因此:

平均 RT 适合观察整体趋势,但不能替代尾延迟指标。


6. Little’s Law:把并发、QPS 和 RT 串起来

这是理解高并发最重要的公式之一。

排队论中的 Little’s Law:

L = λW

其中:

L = 系统中的平均任务数量
λ = 平均到达率
W = 平均停留时间

放到 HTTP 服务中,可以近似理解为:

平均并发数
≈
平均 RPS × 平均响应时间

例如:

RPS = 1000
RT = 100ms

因为:

100ms = 0.1s

所以:

Concurrency
≈
1000 × 0.1
≈
100

也就是说:

1000 RPS
100ms RT

系统中平均大约有:

100 个在途请求

如果 RT 变成 1 秒

还是:

RPS = 1000

但:

RT = 1s

那么:

Concurrency
≈
1000 × 1
≈
1000

并发数量从:

100

增加到:

1000

如果 RT 变成 10 秒

那么:

Concurrency
≈
1000 × 10
≈
10000

此时:

RPS 没变

但是:

在途请求
100 → 10000

增加了 100 倍。

这就是高并发系统中非常重要的一个现象:

系统变慢以后,即使流量没有增加,并发数也可能快速增加。


7. 为什么请求变慢会导致系统雪崩?

假设系统正常情况下:

RPS = 1000
RT = 100ms

因此:

平均并发 ≈ 100

现在 MySQL 出现问题:

SQL RT
100ms → 2s

整个 HTTP 请求:

RT
100ms → 2s

那么:

平均并发
≈
1000 × 2
=
2000

系统中的在途请求从:

100

增加到:

2000

接下来可能出现:

请求增加
   ↓
数据库变慢
   ↓
HTTP RT 增加
   ↓
在途请求增加
   ↓
连接池被占满
   ↓
请求排队
   ↓
RT 进一步增加
   ↓
更多请求堆积

最终形成:

下游变慢
   ↓
请求堆积
   ↓
资源耗尽
   ↓
系统进一步变慢

这就是为什么高并发系统不仅要关注:

CPU
QPS

还必须关注:

RT
连接池
队列长度
超时
资源利用率

8. 并发数、连接数和 QPS 不能混为一谈

这几个概念在实际开发中非常容易混淆。

并发请求

当前正在处理的请求数量

例如:

1000 个请求正在等待完成

可以说:

约 1000 并发请求

TCP 连接数

当前建立的 TCP 连接数量

例如:

10000 TCP Connections

并不意味着:

10000 个请求正在执行

因为一个 TCP 连接可能:

空闲
保持 Keep-Alive
正在传输请求
正在传输响应

HTTP/1.1 可以在连接上复用多个请求,但具体是否以及如何复用取决于连接状态和协议行为;HTTP/2 则可以在一个连接上并发承载多个 Stream。

所以:

连接数 ≠ 请求并发数

QPS

表示:

单位时间内完成多少请求/查询

所以:

Connections
Concurrency
QPS

分别描述:

连接规模
在途任务规模
处理速率

这是三个完全不同的维度。


9. 一个真实的性能指标应该怎么看?

假设压测得到:

RPS      = 5000
Average RT = 30ms
P95      = 60ms
P99      = 120ms
CPU      = 65%
Memory   = 55%
Error    = 0.01%

我们至少可以知道:

吞吐量:5000 RPS
平均响应时间:30ms
P99:120ms
CPU:65%
错误率:0.01%

根据 Little’s Law:

平均并发
≈
5000 × 0.03
≈
150

也就是说:

5000 RPS
30ms 平均 RT

对应平均大约:

150 个在途请求

但这仍然不能说明系统一定可以“稳定支持 5000 并发”。

因为还需要知道:

数据库情况
Redis 情况
网络带宽
连接池
最大连接数
请求分布
P99
P999
错误率
测试持续时间

尤其是压测不能只跑几秒钟。

一个短时间的峰值结果:

5000 RPS

和系统持续几十分钟甚至数小时仍然稳定:

5000 RPS

是完全不同的能力。


10. 高并发最终是在解决什么问题?

到这里,我们可以把前面的概念统一起来:

                 请求到达
                    │
                    ▼
                  RPS
                    │
                    ▼
               在途请求数量
                    │
                    ▼
                 并发数
                    │
                    ▼
              CPU / IO / 网络
                    │
          ┌─────────┼─────────┐
          ▼         ▼         ▼
        Redis     MySQL      RPC
          │         │         │
          └─────────┼─────────┘
                    ▼
                  RT
                    │
                    ▼
                  响应

可以把几个核心指标理解成:

指标关注的问题
RPS / QPS每秒处理多少请求/查询
TPS每秒完成多少事务
并发数同时有多少任务处于进行状态
RT一个请求需要多长时间完成
P95/P99尾部请求到底有多慢
Connection当前有多少网络连接
吞吐量单位时间完成多少工作
Error Rate请求失败比例

这些指标共同描述一个系统的运行状态。

所以真正的高并发问题不是:

“怎么让服务器处理 10 万请求?”

而是:

在大量请求同时存在的情况下,如何让整个系统持续、稳定、可预测地完成这些请求。

这就需要考虑:

并发模型
    ↓
CPU
    ↓
IO
    ↓
连接池
    ↓
数据库
    ↓
缓存
    ↓
队列
    ↓
限流
    ↓
背压
    ↓
超时
    ↓
熔断
    ↓
降级

因此,高并发从来不是某一个组件的问题,而是整个请求链路的容量问题。


总结

这一篇最重要的不是记住几个指标,而是建立它们之间的关系。

首先:

并发数 ≠ QPS

并发数表示:

当前有多少任务正在进行

QPS/RPS 表示:

单位时间完成多少请求

其次:

连接数 ≠ 并发请求数

一个 TCP 连接可以处于空闲、保持连接或者承载请求等不同状态。

然后:

QPS ≠ TPS

QPS/RPS 通常描述请求或查询速率,而 TPS 更强调事务完成速率,具体含义取决于系统定义。

最重要的关系是:

平均并发数
≈
平均 RPS × 平均 RT

例如:

1000 RPS × 100ms
≈ 100 并发

如果:

1000 RPS × 5s
≈ 5000 并发

所以:

系统变慢以后,即使 QPS 没有增加,并发请求数量也可能快速增加。

这也是高并发系统容易发生级联故障的重要原因之一。

最终,可以用这样一张图理解整个系列目前建立的知识:

HTTP 请求
    │
    ▼
Socket
    │
    ▼
进程 / 线程 / 协程
    │
    ▼
IO 多路复用 / Event Loop
    │
    ▼
业务代码
    │
    ├── CPU
    ├── Redis
    ├── MySQL
    └── RPC
    │
    ▼
响应时间 RT
    │
    ▼
RPS / QPS
    │
    ▼
在途请求
    │
    ▼
并发数

到这里,我们已经分别理解了:

请求是什么
谁执行请求
如何管理大量 IO
如何衡量并发