Open6

K6を使用した負荷試験

kiddiknkiddikn

k6とは

https://github.com/grafana/k6

  • k6だけじゃググっても出てこない
  • 負荷試験の設定やシナリオをjsでかける
  • load and performance testing industryで培った経験からできたOSS

動かし方

https://github.com/grafana/k6/tree/master/samples
サンプルが多くて良い!

grpcもいける

import grpc from 'k6/net/grpc';
import { check } from "k6";

let client = new grpc.Client();
client.load([], "./grpc_server/route_guide.proto")


export default () => {
    client.connect("127.0.0.1:10000", { plaintext: true })

    const response = client.invoke("main.RouteGuide/GetFeature", {
        latitude: 410248224,
        longitude: -747127767
    })

    check(response, { "status is OK": (r) => r && r.status === grpc.StatusOK });
    console.log(JSON.stringify(response.message))

    client.close()
}
kiddiknkiddikn

概念

  • virtual users (VUs)単位の処理・シナリオを記述する
  • 記述はjs(ES6)でかけて、VU単位の処理をk6が並列で呼び出している感じらしい
  • 各VU単位の処理は分離されたJavaScript runtimeで実行される

初期

とりあえず動かすにはdefaultfunctionが必要。

import http from "k6/http";

export default function() {
    let response = http.get("https://test-api.k6.io");
};
  • このdefault functionが何度も何度も呼び出される

起動

k6 run script.js

初期化

  • init関数と呼ばれる
  • 初期化とかはdefaultの前に呼び出される?
    • オプションや定義はグローバルに定義
  • ローカルのファイルシステムとか他のモジュールを呼び出すことはできない
  • オプション

ライフサイクル

  • init,setup,teardownはdefault functionの前後に呼び出される
  • 上記処理の実行中はVUの番号は0
// 1. init code

export function setup() {
  // 2. setup code
}

export default function (data) {
  // 3. VU code
}

export function teardown(data) {
  // 4. teardown code
}
kiddiknkiddikn

jsonだけっぽいがsetupで作成したデータをdefaultの引数(下だとdata)として受け取れるらしい。良さそう

initでhttp requestした場合は、それもテスト結果の数に含まれるっぽいけど::setup::teardownタグがつくのでフィルタリングはできそう

export function setup() {
  return { v: 1 };
}

export default function (data) {
  console.log(JSON.stringify(data));
}

export function teardown(data) {
  if (data.v != 1) {
    throw new Error('incorrect data: ' + JSON.stringify(data));
  }
}
kiddiknkiddikn

シナリオの中でuniqueデータを取得する

https://k6.io/docs/examples/data-parameterization#retrieving-unique-data

各iterationで固有の値を取得できそう

scenario.iterationInTest
つまり、1回のシナリオ実行で固有の数値を得られる
別のVUでも重複しない負荷試験で実行される全シナリオを通して一意

VU単位でuniqueな値

vu.idInTest
VUの中で一意なので、別の並列で実行しているVU同士ではかぶることがある
1VUが複数iterationを回したときは、1VU内の各iterationでは一意な値を取得できる