lyyyuna 的小花园

动静中之动, by

RSS

k6 场景的使用

发表于 2026-03
场景 -> Scenarios

什么是场景

前面的文章在介绍 HTTP 请求标签时简单提过 scenario,这篇来详细展开。

场景(Scenarios)用于精细控制 VU 和迭代的调度方式。通过场景,你可以在同一个脚本中模拟不同的负载模式——比如一部分用户稳定访问首页,另一部分用户以递增的速率发起搜索请求。

场景的好处:

配置场景

options 对象中使用 scenarios 来配置。每个场景的名称必须唯一:

export const options = {
  scenarios: {
    example_scenario: {
      // 执行器名称
      executor: 'shared-iterations',

      // 通用配置
      startTime: '10s',
      gracefulStop: '5s',
      env: { EXAMPLEVAR: 'testing' },
      tags: { example_tag: 'testing' },

      // 执行器特有配置
      vus: 10,
      iterations: 200,
      maxDuration: '10s',
    },
    another_scenario: {
      /*...*/
    },
  },
};

场景的通用选项如下:

选项 类型 说明 默认值
executor(必填) string 执行器名称 -
startTime string 相对于测试开始的延迟时间 "0s"
gracefulStop string 迭代结束前的等待时间 "30s"
exec string 要执行的导出函数名 "default"
env object 场景专属的环境变量 {}
tags object 场景专属的标签 {}

执行器

每个场景的核心是执行器(Executor),它决定了负载的调度方式。k6 提供了 7 种执行器,分三大类:

按迭代次数

按 VU 数量

按到达率

开放模型 vs 封闭模型

这 7 种执行器背后有两种调度模型,理解这个区别对设计压测很重要。

封闭模型(Closed Model)

constant-vusramping-vus 属于封闭模型——上一次迭代结束后,下一次迭代才开始。这意味着被测系统的响应时间会影响实际吞吐量:系统越慢,迭代完成得越慢,新请求的到达率也就越低。

export const options = {
  scenarios: {
    closed_model: {
      executor: 'constant-vus',
      vus: 1,
      duration: '1m',
    },
  },
};

export default function () {
  // 这个请求大约需要 6 秒
  // 所以 1 分钟内大约只能完成 10 次迭代
  http.get('https://quickpizza.grafana.com/api/delay/6');
}

在某些测试文献中,这个问题被称为 "coordinated omission"——系统越慢,压力反而越小,这和真实场景可能不一致。

开放模型(Open Model)

constant-arrival-rateramping-arrival-rate 属于开放模型——新迭代的启动和上一次迭代是否完成无关。即使被测系统变慢,请求到达率也保持不变(或按配置变化)。

import http from 'k6/http';

export const options = {
  scenarios: {
    open_model: {
      executor: 'constant-arrival-rate',
      rate: 1,
      timeUnit: '1s',
      duration: '1m',
      preAllocatedVUs: 20,
    },
  },
};

export default function () {
  // 不管这个请求多慢,新迭代都会以每秒 1 次的速率启动
  // 1 分钟内会产生 60 次迭代
  http.get('https://quickpizza.grafana.com/api/delay/6');
}

如果你的目标是模拟固定的请求到达率(比如每秒 100 个请求),用开放模型;如果你的目标是模拟固定数量的并发用户,用封闭模型。

完整示例

下面的脚本组合了两个场景,演示顺序执行:

import http from 'k6/http';

export const options = {
  scenarios: {
    shared_iter_scenario: {
      executor: 'shared-iterations',
      vus: 10,
      iterations: 100,
      startTime: '0s',
    },
    per_vu_scenario: {
      executor: 'per-vu-iterations',
      vus: 10,
      iterations: 10,
      startTime: '10s',
    },
  },
};

export default function () {
  http.get('https://test.k6.io/');
}

运行后 k6 会分别报告每个场景的指标:

scenarios: (100.00%) 2 scenarios, 20 max VUs, 10m40s max duration (incl. graceful stop):
         * shared_iter_scenario: 100 iterations shared among 10 VUs
         * per_vu_scenario: 10 iterations for each of 10 VUs (startTime: 10s)

输出结果中还会按场景分别列出 HTTP 指标,方便对比分析。

lyyyuna 沪ICP备2025110782号-1