負荷テスターアプリケーション

負荷テスターアプリは、 DirectX Cube サンプル統合 サンプルをテストするために作成されたシンプルなアプリケーションで、Node.js アプリケーションと Python スクリプトで構成されています。このアプリをカスタマイズすれば、開発中のプロジェクトのテストを行うことができます。

Node.js テストアプリ

このアプリは TypeScript で書かれており、Genvid API が Node.js で動作するように、Web ソケットの統合とエミュレートされたウィンドウオブジェクトを提供します。

このアプリケーションは 5 つのファイルで構成されます。

  • config.ts: 環境から抽出したグローバル設定。
  • common.ts: コードの他の部分で使用される一般的なユーティリティメソッド。
  • session.ts: Genvid サービスへの接続テストに使用します。以下の機能を有しています。
    • Genvid クライアントの作成とシステムへの接続
    • イベントの送信
    • メトリクス収集と、statsd への送信
  • cube_client.ts: Cube サンプルで使用するためにカスタマイズされた GenvidSession が含まれています。特に、セッションをクラスタに接続するための抽象的な join メソッドの実装が含まれています。
  • index.ts: システムへのエントリポイント。これは定期的にセッションを作成します。

最も重要な部分については、以下で説明します。

CubeSession class

CubeSession class は、 GenvidSession class を拡張して、イベントの送信を許可する join メソッドを実装します。 this.clientIGenvidClient() のインスタンスにアクセスし、 this.statsd のメンバーから自分のスタッツを追加することができます。 app/src/cube_client.ts で定義します。

const cubes = ["Porthos", "Aramis", "Athos"];
const colors = ["green", "white", "yellow", "dark blue", "gray", "light blue", "orange", "blue", "purple"];

// Start of CubeSession class
/**
 * Derived class for customization of the Genvid Session.
 */
export class CubeSession extends GenvidSession {

    /*
     * Call the join method. 
     */
    protected async join(): Promise<genvid.IChannelJoinResponse> {
        const res = await axios.post(config.JOIN_URL);
        const response = res.data as genvid.IChannelJoinResponse;
        if (config.WEBSOCKET_URL) {          
            response.uri = config.WEBSOCKET_URL;
        }
        if (config.NTP_URL) {
            response.info.ntpuri = config.NTP_URL;
        }
        return response;
    }

    public async run() {
        await this.init();
        try {
            await this.start();
            while (true) {
                // Send events every seconds
                this.sendEvent();
                await sleep(1000);
            }
        } catch (err) {
            console.log("Error during session.");
            console.error("Error during session: ", err);
            this.statsd.increment("cube.errors");
            throw err;
        }
    }

    /**
     * Send an event to the system
     */
    public sendEvent(): void {
        if (!this.connected) {
            return;
        }
        try {
            // Send a cheer event
            let cube = cubes[Math.floor((Math.random() * cubes.length))];
            this.client.sendEventObject({ cheer: cube });

            // Send a changeColor event
            let color = colors[Math.floor((Math.random() * colors.length))];
            let evt = {
                key: ["changeColor", cube],
                value: color,
            };
            this.client.sendEvent([evt]);
            this.statsd.increment("cube.sendevents");
        } catch (err) {
            console.log("Send event error");
            console.error("Send event error:", err);
            this.statsd.increment("cube.sendeventerrors");
        }
    }
}

負荷テスターのメインループ

負荷テスターのメインループは、次のような処理を行います。

  • ノード・サーバーのコンテキストで動作するように Genvid ライブラリを初期化します。
  • 定期的に統計量を表示するループを作成します。
  • 新規にセッションを作成し、 run メソッドを呼び出して、ランダムな間隔で N 個のセッションを作成します。

ループの動作を変更する方法については 設定ファイル のセクションを参照してください。

async function main() {
    // Run x connections to the web site, with a random
    // interval between them.
    let promises = []; 
    for (let index = 0; index < config.nbConnection; index++) {
        promises.push(new Session().run());
        const interval = config.intervalMS * (1 + Math.random() * 0.20);
        await sleep(interval);
    }
    return Promise.all(promises);
}

try {
    console.log(`nb connection: ${config.nbConnection}`);
    // Initialize the mock object.
    initMock();
} catch (err) {
    console.log(err);
}

// Print stats every 5 seconds
setInterval(() => {
    Session.printStats();
}, 5000);

main().catch(err => { 
    console.log(`Test execution error: ${err}`);
});

設定ファイル

ロードテスターの設定は、 config/loadtester.hcl の下にあります。関連するパラメータのカスタマイズセクションと同様に、ロードテスタークライアントのためのジョブとログの定義があります。

該当箇所は以下の通りです。

config {
  custom {
    loadtester {
      // The number of connection to create
      connections = 10
      // The interval at witch to create session
      interval    = 1000
      // join URL
      join_url = "http://[::1]:30000/api/public/channels/join"
      // websocket URL. Left empty if not use.
      websocket_url = ""
      // NTP url.  Left empty if not use.
      ntp_url = ""
      // Use telegraf format for statsd.
      telegraf = true
    }
  }
}

Python スクリプト

Python スクリプトは、負荷テストを実行するクラスタを構成します。設定は config/loadtester.hcl ファイルで行います。

重要な構成には次のようなものがあります。

  • connections : 接続数。
  • interval : セッションの作成間隔。