k6を使って負荷テストをやってみる


はじめに

負荷テスト=JMeterって疑いもなく思っていましたが、k6というパフォーマンス計測ツールを知ったので、試してみました。

公式サイトはこちら
https://k6.io/

JavaScriptで負荷テストのコードが書けるのですごく便利です。

環境

  • Windows 10
  • WSL2
  • Docker Desktop
  • Ubunt 20.04

インストール

インストールしてもいいのですが、Dockerコンテナが提供されているので、それを利用することもできます。

公式サイトに従って、インストールします。

$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 379CE192D401AB61
$ echo "deb https://dl.bintray.com/loadimpact/deb stable main" | sudo tee -a /etc/apt/sources.list
$ sudo apt-get update
$ sudo apt-get install k6

Docker使うなら、こうですね。

$ docker pull loadimpact/k6

負荷シナリオを書く

負荷シナリオはJavaScriptで書きます。以下のような形になるのですが、
リクエストの部分を、シナリオ風にしてもいいし、同じリクエストを繰り返して実行することもできます。
使えるAPIはマニュアルを見るのが一番ですね。こちら
あとは、サンプル集も参考になります。こちら

import http from "k6/http";
import { check } from "k6";

// 最初に1回だけ実行される
export function setup() {
    console.log("setup");
}

// ここにテストシナリオを記載する
export default function() {
    let url = 'http://xxxxxx.com/api/xxxxx/xxxx';
    const payload = JSON.stringify(data);

    const params = {
        headers: {
          'Content-Type': 'application/json;charset=UTF-8',
            }
        };

    const response = http.post(url, payload, params);
};

// 最後に一回実行される
export function teardown(data) {
    console.log("teardown");
}

負荷シナリオを実行する

では実行してみます。

k6 run example.js

と実行すると、こんな感じで実行結果が得られます。

    data_received..............: 14 MB  79 kB/s
    data_sent..................: 8.1 MB 45 kB/s
    http_req_blocked...........: avg=1.96ms   min=200ns   med=300ns    max=3.19s    p(90)=700ns    p(95)=1.1µs
    http_req_connecting........: avg=1.64ms   min=0s      med=0s       max=3.16s    p(90)=0s       p(95)=0s
    http_req_duration..........: avg=129.67ms min=41.77ms med=115.8ms  max=1.39s    p(90)=163.85ms p(95)=187.93ms
    http_req_receiving.........: avg=345.74µs min=21µs    med=99.05µs  max=213.61ms p(90)=326.04µs p(95)=565.87µs
    http_req_sending...........: avg=258.93µs min=25.2µs  med=112.6µs  max=91.84ms  p(90)=318.97µs p(95)=444.83µs
    http_req_tls_handshaking...: avg=226.59µs min=0s      med=0s       max=107.53ms p(90)=0s       p(95)=0s
    http_req_waiting...........: avg=129.07ms min=41.63ms med=115.38ms max=1.39s    p(90)=163.16ms p(95)=187.02ms
    http_reqs..................: 7224   39.837763/s
    iteration_duration.........: avg=999.17ms min=1.3µs   med=995.64ms max=4.16s    p(90)=1.04s    p(95)=1.06s
    iterations.................: 7224   39.837763/s
    vus........................: 7      min=7  max=40
    vus_max....................: 40     min=40 max=40

http_req_duration、http_reqsあたりが、性能指標値として使いやすいかと思います。

ユーザ数や実行時間などを指定する

よく使うオプションを紹介します。

-u ユーザ数を指定する 5、10
-d 実行時間を指定する 180s、10m、などを指定する。デフォルト値は30秒
--rps 指定したスループットになるように時刻を調整

 k6 run -u 180 -d 180s --rps 180

実行結果をinfluxdbに登録する

k6には標準で、便利な機能が備わっていて、influxdb実行結果を登録することができます。

 k6 run  --out influxdb=http://localhost:8086/k6db -u 180 -d 180s --rps 180

k6dbというローカルに立てたinfluxdbに登録できます。その結果をGrafanaでグラフ化。
わずか1時間程度で、計測→集計が完了。超らくちん。こんなグラフがすぐできます。

さいごに

JMeterに代わるものとして、k6を使ってみました。
今回、新しいAPIの機能の性能計測に利用しましたが、使い始めてから計測、評価完了まで1週間もかからず。
JavaScriptなので学習コストも低く、influxdbとの連携で、ログの集計とかもらくちんでした。

もう少し大きいシナリオを書いたりすると、少し難しい面も出てくる気がしますが、
現時点では、すごくいいツールという感想です。

またほかの機能を使ってみたら記事にしようとおもいます。