压力测试(Stress Testing)

压力测试(Stress Testing)

一句话总结:测试系统在超出预期负载下的表现,找出系统的极限和崩溃点。

🌟 快速理解

就像测试桥梁承重极限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
桥梁设计:最大承重100吨

负载测试:
- 50吨:正常通行 ✅
- 80吨:正常通行 ✅
- 100吨:正常通行 ✅

压力测试:
- 120吨:桥梁开始晃动 ⚠️
- 150吨:桥梁出现裂缝 ❌
- 180吨:桥梁坍塌 💥

目的:
- 找出桥梁的极限承重
- 了解桥梁的失效模式
- 制定安全措施

📌 核心概念

什么是压力测试?

压力测试:测试系统在超出预期负载下的表现,找出系统的极限和崩溃点。

压力测试 vs 负载测试

维度 压力测试 负载测试
目的 找出极限 验证正常负载
负载 超出预期 预期负载
关注点 崩溃点、恢复能力 响应时间、吞吐量
结果 系统极限 性能指标

🎯 真实案例

案例:Twitter压力测试

背景:2014年世界杯决赛,Twitter预计流量激增

压力测试目标

1
2
3
预期负载:每秒10万条推文
压力测试:逐步增加到每秒50万条推文
目的:找出系统极限

压力测试过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from locust import HttpUser, task, between

class TwitterUser(HttpUser):
wait_time = between(0.1, 0.5) # 高频请求

@task
def post_tweet(self):
"""发推文"""
self.client.post("/tweet", json={
"content": "Goal! #WorldCup"
})

# 压力测试配置
# 用户数:从10万逐步增加到100万
# 增长速率:每秒增加1万用户
# 持续时间:直到系统崩溃

测试结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
负载级别 | 并发用户 | TPS | 响应时间 | 错误率 | 状态
--------|---------|-----|---------|--------|------
100% | 10万 | 10万 | 100ms | 0% | 正常 ✅
200% | 20万 | 18万 | 500ms | 2% | 降级 ⚠️
300% | 30万 | 22万 | 2000ms | 10% | 严重降级 ❌
350% | 35万 | 15万 | 5000ms | 30% | 部分崩溃 💥
400% | 40万 | 5万 | 超时 | 80% | 完全崩溃 💥

发现问题:
1. 数据库连接池耗尽(30万用户时)
2. 内存溢出(35万用户时)
3. 服务器崩溃(40万用户时)

极限:
- 最大并发用户:35万
- 最大TPS:22万
- 崩溃点:40万用户

优化措施

1
2
3
4
1. 增加数据库连接池大小
2. 优化内存使用(减少对象创建)
3. 增加服务器数量
4. 实施限流机制(超过30万用户时拒绝新请求)

✅ 压力测试流程

1. 确定压力目标

1
2
3
4
5
压力目标:
- 起始负载:预期负载的100%
- 最大负载:预期负载的500%
- 增长速率:每分钟增加10%
- 持续时间:直到系统崩溃或达到最大负载

2. 设计压力场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from locust import LoadTestShape

class StressTestShape(LoadTestShape):
"""压力测试:逐步增加负载直到系统崩溃"""

def tick(self):
run_time = self.get_run_time()

# 每分钟增加1000用户
current_users = int(run_time / 60) * 1000

# 最大50000用户
if current_users < 50000:
return current_users, 100
else:
return None

3. 执行压力测试

1
2
3
4
5
# 使用K6执行压力测试
k6 run --vus 50000 \
--duration 1h \
--rps 100000 \
stress-test.js

4. 分析崩溃点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
崩溃点分析:
================
崩溃负载:40000用户
崩溃原因:
1. 数据库连接池耗尽
2. 内存溢出
3. CPU 100%

失效模式:
- 响应时间急剧增加
- 错误率急剧增加
- 部分服务不可用
- 最终完全崩溃

恢复能力:
- 减少负载后,系统能否自动恢复?
- 恢复时间:5分钟

📊 压力测试类型

1. 峰值压力测试

1
2
3
4
5
6
7
目的:测试系统在短时间内承受极高负载的能力

场景:
- 正常负载:1000用户
- 突然增加到:10000用户
- 持续时间:5分钟
- 然后恢复到:1000用户

2. 持续压力测试

1
2
3
4
5
6
目的:测试系统在长时间高负载下的稳定性

场景:
- 负载:预期负载的150%
- 持续时间:24小时
- 观察:内存泄漏、性能下降

🛠️ 压力测试工具

工具 特点 推荐度
K6 高性能、云原生 ⭐⭐⭐⭐⭐
Locust Python、易用 ⭐⭐⭐⭐⭐
JMeter 功能丰富 ⭐⭐⭐⭐
Gatling 高性能 ⭐⭐⭐⭐

📊 最佳实践

1. 逐步增加压力

1
2
3
4
5
6
7
8
9
10
11
12
13
# 错误做法:直接施加最大压力
users = 50000 # ❌

# 正确做法:逐步增加压力
class GradualStressShape(LoadTestShape):
def tick(self):
run_time = self.get_run_time()

# 每分钟增加10%
stage = int(run_time / 60)
users = 1000 * (1.1 ** stage)

return int(users), 100

2. 监控系统状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 监控指标
critical_metrics:
- response_time
- error_rate
- cpu_usage
- memory_usage
- database_connections
- thread_count

# 告警阈值
alerts:
- response_time > 5000ms
- error_rate > 50%
- cpu_usage > 95%
- memory_usage > 90%

3. 测试恢复能力

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def test_recovery():
"""测试系统恢复能力"""

# 1. 施加压力
apply_stress(users=50000)

# 2. 等待系统崩溃
wait_for_crash()

# 3. 减少负载
reduce_load(users=1000)

# 4. 观察恢复
recovery_time = measure_recovery_time()

# 5. 验证功能
assert system_is_functional()

🔗 相关主题

  • [[负载测试]] - 测试预期负载
  • [[性能测试]] - 包含压力测试
  • [[耐力测试]] - 长时间压力测试

💡 快速参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
压力测试速查表
================

定义:测试系统在超出预期负载下的表现

核心目标:
🎯 找出系统极限
💥 发现崩溃点
🔄 测试恢复能力

压力测试流程:
1. 确定压力目标
2. 设计压力场景
3. 执行压力测试
4. 分析崩溃点

压力测试类型:
- 峰值压力测试(短时间极高负载)
- 持续压力测试(长时间高负载)

推荐工具:
- K6(高性能)
- Locust(易用)
- JMeter(功能丰富)

最佳实践:
1. 逐步增加压力
2. 监控系统状态
3. 测试恢复能力
4. 记录崩溃点

压力 vs 负载:
- 压力:超出预期、找极限
- 负载:预期负载、验证性能

关键指标:
- 崩溃点(最大负载)
- 失效模式(如何崩溃)
- 恢复时间(多久恢复)