服务器如何模拟真实访问做压测

chinaz
chinaz 初级会员超兽战士
发布于 2026-10-08 09:16 ·3 浏览 ·0 回复

学完这篇,你能从零搭出一套「像真人一样访问」的压测方案:不再是 curl 循环刷一个接口,而是还原登录态、混合接口、思考时间和逐步加压,最终拿到可信的 QPS、P95 延迟和拐点数据。

第一步:先定指标,别急着敲命令

这一步要产出的是「一张压测目标表」,没有它,跑完你也不知道合格不合格。至少要写清四项:

  • 目标 QPS:比如 800 req/s
  • P95 延迟:比如 < 300ms
  • 错误率:比如 < 0.1%
  • 并发用户数:比如 200 VU(虚拟用户)

注意:P95 比平均值重要得多。平均 50ms 而 P95 是 2s,说明有 5% 的用户在骂人。

第二步:准备干净的环境和真实量级的数据

压测机不能和被测服务抢 CPU,数据量级要接近生产(比如生产 500 万条订单,你拿 1000 条测,缓存全命中,结果毫无意义)。

准备测试账号和 ID 池:

seq 1 50000 | shuf > uids.txt   # 5 万个随机商品/用户 ID

注意:绝对不要直接压生产库。要么用独立压测环境,要么用只读影子库,否则压测写进去的垃圾订单清理起来很痛苦。

第三步:先用 ab 打一个基线

这一步要的是「单接口天花板」,方便后面和真实场景对比。用 ApacheBench 在压测机上执行:

ab -k -n 20000 -c 200 \
  -H "Authorization: Bearer eyJhbGci..." \
  -H "User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_0)" \
  "http://10.0.0.5:8080/api/v1/items/1001"
  • -k 开启长连接(不加就是 HTTP/1.0 短连接,结果偏低)
  • -n 总请求数,-c 并发数

注意:ab 是单进程单线程,本机并发超过 500 时压测机自身可能先跑满 CPU。可用 top 看一眼,压测机 CPU > 80% 时结果不可信。

第四步:用 k6 写「真人行为」脚本

这一步要的是最接近真实用户流量的脚本。k6 是单文件二进制,装完直接跑,脚本用 JavaScript 写。核心是把「随机参数 + 登录态 + 思考时间 + 混合请求」都写进去:

import http from 'k6/http';
import { sleep, check } from 'k6';

export const options = {
  scenarios: {
    real_user: {
      executor: 'ramping-vus',
      stages: [
        { duration: '1m', target: 50 },
        { duration: '2m', target: 100 },
        { duration: '2m', target: 200 },
        { duration: '1m', target: 0 },
      ],
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<300'],
    http_req_failed: ['rate<0.001'],
  },
};

const BASE = 'http://10.0.0.5:8080';

export default function () {
  // 随机商品 ID,避免缓存全命中
  const id = Math.floor(Math.random() * 50000) + 1;

  const res = http.get(`${BASE}/api/v1/items/${id}`, {
    headers: {
      'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)',
      'Authorization': `Bearer ${__ENV.TOKEN}`,
      'Accept': 'application/json',
    },
  });
  check(res, { 'status is 200': (r) => r.status === 200 });

  // 思考时间 1~3 秒,模拟人在看页面
  sleep(Math.random() * 2 + 1);

  // 10% 的用户会下单
  if (Math.random() < 0.1) {
    http.post(`${BASE}/api/v1/orders`,
      JSON.stringify({ itemId: id, count: 1 }),
      { headers: { 'Content-Type': 'application/json',
                   'Authorization': `Bearer ${__ENV.TOKEN}` } });
  }
  sleep(1);
}

运行:

k6 run -e TOKEN=eyJhbGci... --out json=result.json loadtest.js

注意:sleep() 千万别省。没有思考时间的压测等于用机器人狂点,测出来的 QPS 会虚高好几倍,上线就雪崩。

第五步:阶梯加压,找拐点

k6 的 stages 已经帮你做了:50 → 100 → 200 VU 每档跑 2 分钟。重点盯三个指标随并发的变化曲线:

  • QPS 涨不动了 → 到了容量拐点
  • P95 突然从 200ms 跳到 1.5s → 队列开始堆积
  • 错误率从 0 抬头 → 要么超时,要么连接池打满

同时登录被压服务器看 top、vmstat 1、GC 日志和数据库慢查询,确认瓶颈在 CPU、连接池还是慢 SQL。

第六步:记录并清理

把脚本、参数、目标表、监控截图一起归档,下次回归直接对比。压测产生的订单、账号用脚本按 create_time 批量删掉。

注意:如果服务开了限流或 WAF,压测流量会被拦截,错误率飙升却不代表服务有问题。压测前先在上游网关把你的压测机 IP 加白名单。

小结

  • 先定指标(QPS、P95、错误率、并发),再动手压
  • 数据量级和请求头要还原真实,ID 必须随机化,否则缓存骗你
  • 思考时间 sleep() 是真实感的灵魂,不能省
  • 用 ab 打单接口基线,用 k6 做混合场景 + 阶梯加压
  • 盯拐点而不是盯平均值,压测机自身 CPU 别超过 80%
  • 环境隔离、数据清理、限流白名单,三件事提前做
版权声明:本文来自 GJ站长论坛《服务器如何模拟真实访问做压测》
原文链接:https://www.gj0.com/thread-866.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。

全部回复 0

还没有回复,来抢沙发~