EventBridgeを利用した負荷テスト

Posted on 2022/02/11

ToC

本番ワークロード相当で負荷テストを実施したい…

アプリケーションの内部の仕組みの見直しとリファクタリングを実施しています。
機能リグレッションテストも行われているので、本番ワークロードレベルでの負荷をかけてみたいと考えました。

本番環境のワークロードをマスクしたデータまでは準備したのですが、このワークロード量が「数台のEC2で発生できるレベルではない」さらに 「ワークロード量が時間帯によって大きく変動する」という特性があります。 こうした大量のイベントをスケジューリングしながら発生させるテストアプリケーションの作成は、割と敷居が高いので少し困っていました。

/posts/2022/02/img/5fc428d6_hu76e605a13407ea5055575d85951b482c_10339_336x0_resize_lanczos_3.png

色々と調査していたところ、Amazon EventBridge に ArchivesReplays というイベントを再実行して再現できる機能があることが わかりました。これを活用すればうまくいくかもしれない…. というところから、検証してみました。 AWS機能の詳細は、Amazon EventBridge でイベントをアーカイブおよびリプレイするのブログにあります。

今回の検証構成

今回の検証は、2つのステップに段階を分けて実施します。
Step1では、テストデータの登録のためにカスタムEventbusにArchivesを設定し、テスト用のワークロードをCLIを用いて登録して登録します。
Step2で、Replaysの機能を利用してテストを実行していきます。

/posts/2022/02/img/5ebac0ae_hueef8764552366f256d998c5ec5b1e6a8_32405_454x0_resize_lanczos_3.png

Step1: テストデータの登録

Eventbusの作成とArchive設定

Cloudformationが、Archivesにも対応しているためテンプレートを簡単に作成することができます。 Amazon EventBridgeをはじめてみるにて、作成したテンプレートを少し改良して作成しました。 Archivesの対象とするイベントは、条件設定をすることができるため登録予定のワークロードのSourceの条件を指定し、保持期間を10日と設定しました。

AWSTemplateFormatVersion: "2010-09-09"
Description: Event Bridge Template

Parameters:
  CanonicalName:
    Type: String
    Default: my-canonical-name
    AllowedPattern: "[-a-zA-Z0-9]*"
    ConstraintDescription: ""

Resources:
  EventBus:
    Type: AWS::Events::EventBus
    Properties:
      Name: !Sub "${CanonicalName}-event-bus"

  Archive:
    Type: AWS::Events::Archive
    Properties:
      ArchiveName: Archive
      EventPattern:
        source:
          - "net.my-super-company"
      RetentionDays: 10
      SourceArn: !GetAtt EventBus.Arn

Outputs:
  EventBus:
    Value: !Ref EventBus
  Archive:
    Value: !Ref Archive

ワークロードの登録

イベントデータの登録は、Cloudwatch Events CLIの put-events を利用して登録します。
テスト用のワークロードを登録する際に、正しい時間タイミングでCLIを呼び出す必要があると、結局はツールを作ることと同じになってしまいます。

ここでポイントとなるのは、put-eventsTimeの要素です。
明示的にテスト用のワークロードデータに事前にTimeの要素を指定しておくことで、データの投入タイミングが制御できます。 これで、APIの呼び出しタイミングによらずスケジュールされたテストワークロードを作成することができます。(本当に素晴らしい機能です)
ちなみに、Time要素を指定しない場合には、APIの呼び出し時間が利用されるようです。

スクリプトとテストワークロードの一部

#!/bin/bash
aws events put-events --entries file://events.json
[
  {
    "Time": "2022-02-11T06:41:00.189",
    "EventBusName": "my-canonical-name-event-bus",
    "Source": "net.my-super-company",
    "DetailType": "my-super-detail-type",
    "Detail": "{ \"key1\": \"value1\", \"key2\": \"value2\", \"data\": \"data1\" }",
    "Resources": [
      "resource1",
      "resource2"
    ]
  },
  {
    "Time": "2022-02-11T06:41:00.189",
    "EventBusName": "my-canonical-name-event-bus",
    "Source": "net.my-super-company",
    "DetailType": "my-super-detail-type",
    "Detail": "{ \"key1\": \"value3\", \"key2\": \"value2\", \"data\": \"data2\" }",
    "Resources": [
      "resource1",
      "resource2"
    ]
   }
]

Step2: Replays機能を利用

テストワークロードの登録が完了したので、次にReplays機能を利用して実際にイベントを発生させてみます。
Replay機能は、マネージメントコンソールもしくはCLIを利用して実行します。 実行ソースとなるEventBusやイベントを再実行する対象時間を指定して再実行します。AWSコンソール画面でも直感的に理解できると思います。
なお、Replayの実行の前に Event Ruleを設定してアプリケーションが実行される状態を作っておくことを忘れないでください。

/posts/2022/02/img/9d19aad9_hu2e6f3b3c0156fdd4445b0ca9a024c230_48009_720x0_resize_lanczos_3.png

実際に同じタイミングで複数のイベントを発生させるようなテストワークロードを試してみましたが、テスト対象アプリケーションの Lambdaは期待したように複数起動して処理を実行していました。

この機能を利用することで、複雑性があったり、データ量がそれなりに多いワークロードデータであっても、イベント登録のタイミングを 気にすることなく繰り返しテストができそうです。

今日はこのあたりで….


参照