负载测试和压力
负载测试和压力
1)为什么需要它
目标是:- 确认容量(在给定SLO下系统将承受多少RPS/竞争性会话)。
- 查找瓶颈(CPU/IO/DB/网络/锁定/池)。
- 在CI/CD中设置性能预算和"门"。
- 降低发布风险(p95/p99回归,高峰时错误增加)。
- 计划容量/成本(滑出和储备)。
2)Perf测试的类型
负载(工作负载):逼真的流量接近峰值;SLO验证。
Stress(压力):高达/高于极限→降解行为发生故障。
Spike(脉冲):快速的负载跳跃→弹性/自动轨迹。
Soak/Endurance(延长):小时/天→泄漏,碎片,漂移延迟。
能力/可变性:在尺度输出时如何通过输入/延迟变化;阿姆达尔/古斯塔夫森定律。
Smoke perf:每个发行版(表演三位一体)上的简短"烟雾"运行。
3)交通生成模型
封闭模型(固定的VUs/concurrency):"N"用户,每个用户在客户端中排队查询→队列。隐藏过载的风险。
开放模型(arrival rate):与现实生活中一样,λ强度的应用程序流(req/s)。更适合公共API。
Little定律:"L=λ × W"。
对于池/服务:最小并发性≈ 'λ × W'(添加20-50%的库存)。
其中"λ"是通过输入,"W"是平均维护时间。
4)负载配置文件和脚本
User journey mix:脚本份额(登录,浏览,deposit, checkout……)。
思考时间:用户暂停(分布:指数/lognormal)。
数据配置文件:响应大小、付费、参数变异性。
相关性:将步骤(cookies/tokens/ID)链接为真实的浮动。
冷/热/热kesh:单独运行。
Read vs Write:读数/记录的平衡,retrais的等效性。
多区域:RTT,POP/ASN分布。
5)测试环境
隔离:通过拓扑/设置(但不是"byom "prod)接近展位。
数据: PII掩蔽,卷,索引如销售.
负载发生器:不靠在CPU/网络上;分布式收发器,时间同步。
可观察性:度量/treas/Logs,周边合成,CPU/heap配置文件导出。
6)度量标准和SLI
Throughput:每秒RPS/事务。
Latency: p50/p95/p99, TTFB, server time vs network.
错误:5xx/4xx/域错误的百分比。
Aturation: CPU, load avg, GC, Disk IOps/潜伏期, network, pool wait。
业务SLI:成功存款≤ 5 s,订单确认≤ 2 s。
从SLO中获取阈值(例如"99。95% ≤ 300 ms"),在运行过程中监控燃烧率。
7)寻找瓶颈(技术)
1.将系统稳定预热到60-80%的目标负载。
2.增加步骤(ramp) →固定p95/p99和error-rate生长的位置。
- 在池中排队(DB/HTTP),
- WAIT/locks(DB)的增长,
- GC暂停/跳跃,
- 网络retransmits/packet loss,
- 磁盘隐含性/缓存错误。
- 4.本地化:二进制查询路径搜索、分析仪(CPU/alloc/lock-profile)。
- 5.固定"瓶子"→调整→重复运行。
8)压力下的行为
Graceful degradation:极限,电路断路器,队列与后压,模式"被接受处理"。
Retrai:最多1个,仅偶数;jitter;中继预算≤ RPS的10%。
失败打开/失败关闭:对于非关键依赖项,允许失败打开(kesh/存根)。
Cascading failure:隔离池/配额(bulkhead),快速定时,"平稳"禁用功能(功能页)。
9)工具(按任务选择)
k6 (JavaScript, open/open-model,快速,方便使用CI)。
JMeter(生态系统丰富,GUI/CLI,插件,但较重)。
Gatling(Scala DSL,高性能)。
位置(Python,脚本灵活性)。
Vegeta/hey/wrk(微型基准和快速验证)。
规则:一个"主要"工具+轻量级CLI用于公关中的烟熏。
10)示例(snippets)
10.1 k6(带有arrival rate的开放模型)
js import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
scenarios: {
open_model: {
executor: 'ramping-arrival-rate',
startRate: 200, timeUnit: '1s',
preAllocatedVUs: 200, maxVUs: 2000,
stages: [
{ target: 500, duration: '5m' }, // до 500 rps
{target: 800, duration: '5m'} ,//stress
{ target: 0, duration: '1m' }
]
}
},
thresholds: {
http_req_duration: ['p(95)<300', 'p(99)<800'],
http_req_failed: ['rate<0. 005'],
},
};
export default function () {
const res = http. get(`${__ENV. BASE_URL}/api/catalog? limit=20`);
sleep(Math. random() 2); // think-time
}
10.2 JMeter(配置文件想法)
Thread Group + Stepping Thread или Concurrency Thread (open-like).
HTTP Request Defaults, Cookie Manager, CSV Data Set.
Backend Listener → InfluxDB/Grafana;按时间/代码排序。
10.3 Locust (Python)
python from locust import HttpUser, task, between class WebUser(HttpUser):
wait_time = between(0. 2, 2. 0)
@task(5)
def browse(self): self. client. get("/api/catalog? limit=20")
@task(1)
def buy(self): self. client. post("/api/checkout", json={"sku":"A1","qty":1})
11)数据、相关性、准备
种子数据:目录,用户,资产负债表,代币-如销售。
伪装/匿名PII;在实际分布之上生成合成物。
相关性:从响应(RegExp/JSONPath)中检索ID/令牌,并在后续步骤中使用。
12)运行期间的观察力
沿途的RED dashbords(Rate,Errors,Duration)。
Exemplars:从指标过渡到轨道(trace_id)。
错误日志:sampling+聚合,复制/等效性。
系统:CPU/GC/heap,驱动器/网络,池等待。
DB:顶级查询,锁定,索引扫描,bloat。
13)自动化和表演门
CI:在急流中短暂运行(例如k6 2-3分钟)。
Nightly/Weekly:在单独的环境中漫长的soak/stress;报告和趋势。
金丝雀发行:将SLO(错误率,p95)分析为促销活动的"门户"。
回归:基线vs当前法案;恶化时的异常值>X%。
14)容量规划和成本
曲线throughput→latency:定义knee point(膝盖)-之后,p99会急剧增长。
滑出:测量缩放效率(RPS增量/节点增量)。
费用:"RPS每小时",高峰事件备用+DR备用。
15)反模式
在"空白"环境中进行无控制的prod击球或测试,与prod不同。
带有固定VU的封闭模型,可隐藏过载。
缺乏思考时间/数据→不切实际的kesh命中,反之亦然-风暴到原始人。
单个"/ping"脚本代替自定义的flow。
缺乏可观察性:"只看到RPS和平均延迟"。
不受控制的后退→ DDoS。
在不提交假设/更改的情况下混合测试和优化。
16)支票清单(0-30天)
0-7天
定义SLI/SLO和目标流量配置文件(mix, think-time,数据)。
选择工具(k6/JMeter/Locust),举起RED行列板。
准备展位和种子数据,禁用第三方限制/captchi。
8-20天
构建脚本:开放模型(arrival rate),冷/热/热kesh。
启动load → stress → spike;修复刀尖和瓶颈。
在CI(微运行)中引入性能门。
21-30天
Soak测试4-24小时:泄漏/漂移GC,稳定。
记录极限、容量计划、"RPS→p95/oshibki"插图。
准备"如何增加限制/滑板"和"如何降级"的运行手册。
17)成熟度量
有现实的配置文件(混合,思考时间,数据)覆盖≥ 80%的流量。
RED-dashbords+跟踪已连接至所有测试。
在p95回归/错误时,表演门会阻止发布。
容量和knee点记录在关键服务上。
每月soak/stress运行和动态报告。
自动滑轨和缺少cascade-fail证实了对"spike"的抵抗力。
18)结论
负载测试是常规的工程实践,不是一次性的"测量"。模拟实际用户(开放模式),测量客户体验(SLI/SLO)的反映,在CI/CD中保持可观察性和"网关",进行stress/spike/soak运行并捕获knee点。然后将峰值事件和"黑天鹅"转换为可管理的脚本,并将性能转换为可预测和可衡量的平台参数。