【負荷テスト】k6をgithub actionsで試しに動かす
※ 個人ブログを閉鎖するので個人ブログに書いていたものを転載
GitHub Actionsでk6を使って負荷テストを行う
環境
- k6: v0.42
サンプルコードのリポジトリ
今回使用したサンプルは以下のリポジトリに配置しています。
https://github.com/i-shinya/k6-github-actions-sample
k6をGitHub Actions上で動かす
シナリオファイル
リクエスト先はlocalhost:80
でローカルのnginxに対してのテストです。
import { check } from "k6";
import http from "k6/http";
export const options = {
thresholds: {
http_req_failed: ["rate<0.01"],
http_req_duration: ["p(90)<500", "p(95) < 1000"]
},
stages: [
{ target: 1000, duration: "10s" },
{ target: 2000, duration: "10s" }
]
};
export default function () {
const res = http.get("http://localhost:80");
check(res, {
"is_status_200": (r) => r.status === 200
});
}
GitHub Actionsでのk6負荷テスト
GitHub Actionsで負荷テストを行う方法について解説します。ここでは公式から提供されているk6のActionではなく、手動でk6をインストールして使用します。
workflowファイルの設定
workflow_dispatch
をトリガーとして、RPS(Requests Per Second)を手動で指定できるように設定します。
name: k6-load-test
on:
workflow_dispatch:
inputs:
rps:
description: "k6負荷実行のRPS"
required: true
default: 1000
jobs:
k6test:
name: Run k6 load test
runs-on: ubuntu-latest
services:
nginx:
image: nginx:latest
ports:
- "80:80"
steps:
- name: Checkout
uses: actions/checkout@v2
- name: curl nginx
run: curl http://localhost:80
- name: Install k6
run: |
curl https://github.com/grafana/k6/releases/download/v0.42.0/k6-v0.42.0-linux-amd64.tar.gz -L | tar xvz --strip-components 1
- name: Run k6 load test
run: |
./k6 run simple-k6-sample.js --rps ${{ github.event.inputs.rps }}
実行する!!
github actionsから手動で実行!!RPSはデフォルトとして設定した1000にしました。
k6の実行結果は以下のようになりました。指定した1000 req/secはほぼほぼでてますね!
running (22.0s), 0000/2000 VUs, 21919 complete and 0 interrupted iterations
default ✓ [ 100% ] 0000/2000 VUs 20s
✓ is_status_200
checks.........................: 100.00% ✓ 21919 ✗ 0
data_received..................: 19 MB 850 kB/s
data_sent......................: 1.7 MB 78 kB/s
http_req_blocked...............: avg=49.22µs min=700ns med=2.1µs max=58.43ms p(90)=112.29µs p(95)=229.79µs
http_req_connecting............: avg=39.49µs min=0s med=0s max=58.12ms p(90)=71.59µs p(95)=179.99µs
✓ http_req_duration..............: avg=346.65µs min=127.49µs med=238.89µs max=27.27ms p(90)=463.49µs p(95)=646.7µs
{ expected_response:true }...: avg=346.65µs min=127.49µs med=238.89µs max=27.27ms p(90)=463.49µs p(95)=646.7µs
✓ http_req_failed................: 0.00% ✓ 0 ✗ 21919
http_req_receiving.............: avg=45.63µs min=10.7µs med=30.2µs max=11.95ms p(90)=75.59µs p(95)=110.99µs
http_req_sending...............: avg=18.81µs min=3.2µs med=10.9µs max=11.22ms p(90)=30.3µs p(95)=45.6µs
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=282.2µs min=90.8µs med=187.29µs max=27.24ms p(90)=358.89µs p(95)=522.39µs
http_reqs......................: 21919 996.362275/s
iteration_duration.............: avg=1s min=509.89µs med=1s max=1.99s p(90)=1.79s p(95)=1.89s
iterations.....................: 21919 996.362275/s
vus............................: 831 min=17 max=1916
vus_max........................: 2000 min=2000 max=2000
次はRPSを10000にして実行!10000には届いてないですが、7000 req/secくらいでていますね!(VUsとか調整したらもう少しでるかもしれんけど)
ある程度のアプリであればgithub actions上からの負荷テストで問題ないかもですね。
running (20.1s), 0000/2000 VUs, 139743 complete and 0 interrupted iterations
default ✓ [ 100% ] 0000/2000 VUs 20s
✓ is_status_200
checks.........................: 100.00% ✓ 139743 ✗ 0
data_received..................: 119 MB 5.9 MB/s
data_sent......................: 11 MB 542 kB/s
http_req_blocked...............: avg=2.26ms min=500ns med=1.5µs max=542.83ms p(90)=2.29µs p(95)=4.5µs
http_req_connecting............: avg=1.96ms min=0s med=0s max=542.31ms p(90)=0s p(95)=0s
✓ http_req_duration..............: avg=124.76ms min=118.7µs med=108.86ms max=834.34ms p(90)=243.01ms p(95)=279.66ms
{ expected_response:true }...: avg=124.76ms min=118.7µs med=108.86ms max=834.34ms p(90)=243.01ms p(95)=279.66ms
✓ http_req_failed................: 0.00% ✓ 0 ✗ 139743
http_req_receiving.............: avg=2.69ms min=9µs med=17.6µs max=579.62ms p(90)=10.41ms p(95)=17.64ms
http_req_sending...............: avg=1.82ms min=2.6µs med=6µs max=769.89ms p(90)=125.99µs p(95)=6.48ms
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=120.23ms min=84µs med=104.8ms max=775.69ms p(90)=237.26ms p(95)=271.1ms
http_reqs......................: 139743 6937.269372/s
iteration_duration.............: avg=144.11ms min=183.49µs med=130.13ms max=908.72ms p(90)=253.56ms p(95)=326.03ms
iterations.....................: 139743 6937.269372/s
vus............................: 1919 min=18 max=1919
vus_max........................: 2000 min=2000 max=2000
最後に
github actions上での実行でこれくらいrps出せるのは驚きでした!
困ったこと
公式actionを使うとlocalhostへ通信できない・・・
上でちらっと書いたのですが、公式actionではlocalhostにアクセスできず以下のようなエラーが表示表示されていました。
ログを見たら公式actionはdockerで動いてるためでした。ログをちゃんと読んでなくて解決までに時間かけてしまいました。
time="2022-12-19T14:57:12Z" level=warning msg="Request Failed" error="Get \"http://localhost:80\": dial tcp 127.0.0.1:80: connect: connection refused"
k6バージョンアップによってエラーが・・・
こちらは原因が謎なのですが、私がgithub actionsを追加し動作確認した翌日にv0.41 –> v0.42へバージョンアップが行われたようでそれによりworkflowが失敗するようになりました。
その際はインストール部分を以下のように記述していましたが、v0.41 –> v0.42へバージョンアップされた結果動かなくなりました。インストール方法を上述したものに変更したら動くようになったものの原因は分からず。
apt-getしたものとcurlで取得したものが何か違うのかもしれないですね。
以下は修正する前にapt-getでk6をinstallしたもの。
- name: Install k6
run: |
sudo apt-get update
sudo apt-get upgrade
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
参考
- 公式のactionドキュメント
- k6のインストール手順は以下を参考(公式のものでは動かなかったため)
Discussion