Skip to content

Instantly share code, notes, and snippets.

@voluntas
Last active April 3, 2023 02:59
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save voluntas/5c9e0f778e36c1e934e83611a94ffdfa to your computer and use it in GitHub Desktop.
Save voluntas/5c9e0f778e36c1e934e83611a94ffdfa to your computer and use it in GitHub Desktop.
時雨堂 シナリオ負荷試験ツール Oribe 開発ログ

時雨堂 シナリオ負荷試験ツール Oribe 開発ログ

日時

2018-08-05

時雨堂

バージョン

18.08.0

url

https://shiguredo.jp/

depth

3

概要

時雨堂 で開発している Lua でシナリオを書くことができる負荷試験ツールの開発ログです。パッケージ製品としていは販売を予定していません。

採用事例

Medium

目的

継続的なシナリオベースの負荷試験を気軽にかけられるようなパッケージを提供したい

  • 継続的負荷試験を実現したい
  • 複雑な状態を持ったクライアントの試験を実現したい

負荷試験までの距離をとにかく短くする製品にしたい。

特長

  • 秒間ではなく、仮想ユーザ単位での負荷試験
  • Lua から Erlang で書いたライブラリを読み出すことが可能
  • ユーザごとにシナリオを設定可能
  • 最大 100 万ユーザの負荷
  • 環境構築を簡単に
  • HTTP/1.1 に対応
  • Lua でシナリオを書くことができる
  • 1 ヶ月間負荷をかけ続けるといったロングランに対応
  • 統計情報などはすべて負荷をかけられる側に依存する

スクリプト例

-- 色々便利なライブラリを提供予定
local http = require "oribe.http"
local json = require "oribe.json"
local kvs = require "oribe.kvs"

local body = {username = "test", credential = "pass"}
local json = json.encode(body)
local headers = {["content-type"] = "application/json"}
-- python requests を参考にしてる
local res = http.post("http://192.0.2.10/login", headers, json)
local resp_json = json.decode(res.body)

local body = {secret_key = resp_json.secret_key}
-- post_form で a=b&c=d を投げられる
local res = http.post_form("http://192.0.2.10/get_data", body)
local resp_json = json.decode(res.body)

こんな感じでシナリオが書けます。 戻ってきた情報を元にまた API を叩くことができるという仕組みです。

構成

master

司令塔

minion

VU 管理

  • master 1 と minion N の構成を取ります。 minion は内部で VU を指定された分だけ起動します。
  • minion 5 で minion ごとの VU が 1000 だとすると 5000 VU での負荷試験を行えます。
  • master が同時に実行できるテストは 1 テストのみで、そのテストが終わらない限り別のテストを実行することはできません
    • テストを同時に実行したい場合は複数の master を起動する必要があります

image

API

  • Start
    • minion_num
      • いくつの minion に負荷をかけさせるか
    • vu_num_per_minion
      • 1 minion ごとの VU 数
    • duration_sec
      • 何秒間負荷をかけるか
    • setup_lua_script
      • テスト実行前にミニオンで 1 度だけ実行される Lua スクリプト
      • ここで必要なデータを用意し kvs ライブラリを利用し VU で共有する
    • lua_script
      • 実行する Lua スクリプト
  • Stop
    • 強制ストップ
  • GetStatus
    • 利用できるミニオンの数

提供ライブラリ

local http = require "oribe.http" の用に利用可能です

  • http
    • get
      • ヘッダーも指定可能
    • post
      • ヘッダーも指定可能
    • post_form
      • ヘッダーも指定可能
  • json

    • encode
    • decode
    local ojson = require "oribe.json"
    spam = {1,2,3}
    local j = ojson.encode(spam)
    return ojson.decode(j) 
  • base64
    • encode
    • decode
  • msgpack

    • pack
    • unpack
    local omsgpack = require "oribe.msgpack"
    local msg = "abc"
    local packed = omsgpack.pack(msg)
    local unpacked = omsgpack.unpack(packed)
    return msg == unpacked
  • zlib
    • gzip
    • gunzip
  • client
    • sleep
      • ミリ秒単位でスリープが可能
    • get_id
      • VU に割り振られるシーケンス番号を取得可能
  • crypto

    • hash
      • md5, sha1, sha224, sha256, sha384, sha512 に対応
    • block_encrypt(type, key, iv, plain_text)
      • aes_cbc に対応
    • block_decrypt(type, key, iv, cipher_text)
      • aes_cbc に対応
    • pkcs7_pad(plain_text)
    • pkcs7_unpad(plain-text)
    local ocrypto = require "oribe.crypto"
    local plain_text = "hello world"
    local key = "0123456789012345"
    local iv = "0123456789012345"
    local plain_text_with_pad = ocrypto.pkcs7_pad(plain_text)
    local cipher_text = ocrypto.block_encrypt("aes_cbc", key, iv, plain_text_with_pad)
    local plain_text2_with_pad = ocrypto.block_decrypt("aes_cbc", key, iv, cipher_text)
    local plain_text2 = ocrypto.pkcs7_unpad(plain_text2_with_pad)
    return plain_text == plain_text2
    local ocrypto = require "oribe.crypto"
    local data = "hello world"
    local digest = ocrypto.hash("sha", data)
    return digest
  • kvs

    • このライブラリは minion 単位で共有されます
    • get(key)
    • set(key, value)
    local kvs = require "oribe.kvs"
    local success, err = kvs.set("abc", "xyz")
    local value = kvs.get("abc")

WebSocket 経由でのログ表示

すべての処理が非同期で行われるため、指定した URL に WebSocket を繋ぐことでリアルタイムなログが確認できる。

将来的には管理ツールを提供予定。

終了通知

負荷試験が終了したことを master からの Web フック URL と WebSocket で知ることができる。

ロードマップ

プロトコル

基本的には HTTP API ベースのプロトコルを優先していきます。

  • WebSocket に対応
    • 優先度高め
  • HTTP/2 に対応
    • 優先度高め
  • QUIC に対応
    • いつか
  • gRPC に対応
    • いつか
  • WebRTC に対応
    • いつか
    • 少し特殊な仕組みで提供予定です

管理ツール

Electron を利用した管理ツールを提供予定。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment