Amazon Web Services ブログ

Amazon CloudWatch Evidently による Client-Side Evaluation の紹介

Amazon CloudWatch Evidently を使用すると、ディベロッパーはユーザーに公開する前にごく一部のトラフィックで新機能をテストし、結果を評価できます。Evidently の機能フラグ はリリース前に定義され、実行時にアプリケーションコードがリモートサービスに問い合わせて、特定のユーザーに新機能を表示するかどうかを決定します。ユーザーの機能フラグを取得するためのリモート呼び出しは ネットワークレイテンシー の影響を受けやすく、悪い場合には数百ミリ秒の遅延が発生することもあります。機能フラグの取得に待ち時間が増えると、ミリ秒が重要となるウェブページの速度に直接影響する可能性があります。私たちの解決策は Amazon CloudWatch Evidently による Client-Side Evaluation (クライアントサイドの評価) です。Client-Side Evaluation (クライアントサイドの評価) では、ディベロッパーは機能フラグをローカルで取得し、ネットワークのオーバーヘッドを完全に回避することで、レイテンシーを大幅に削減できます。

ここでの「Client-Side (クライアントサイド )」という用語はブラウザを指すものではありません。ここでの「Client-Side (クライアントサイド )」はリモートAPIコールを通じて行われる操作ではなく、コンテナアプリケーション上で行われる操作のことです。これにより、AWS AppConfig エージェント (コンテナアプリケーションのバックエンドと並行して実行されるサイドカーコンテナ) からユーザーの機能フラグを取得できるため、ネットワーク呼び出しが不要になります。このエージェントにより、コンテナランタイムで AWS AppConfig を利用できるようになります。これは新しいコードをデプロイしなくても、実行中のアプリケーションの動作を変更できるようにするサービスです。この記事ではソリューションアーキテクチャと Amazon Elastic Container Service (Amazon ECS) アプリケーションで Client-Side Evaluation を計測する方法について説明します。

ソリューションの概要

図 1 は Amazon ECS で実行されるアプリケーションで Client-Side Evaluation がどのように動作するかを示しています。ウェブページは、ウェブページのバックエンドを呼び出し、エンドユーザーに表示するウェブサイトの機能を決定します。これがどのように動作するのか見てみましょう。

High-level architecture of Client-side Evaluation for Amazon CloudWatch Evidently

図1. Amazon CloudWatch Evidently の Client-Side Evaluationの高水準アーキテクチャ

  1. AWSコンソールのモバイルアプリケーション、API、または AWS CloudFormation を使用して、Evidently のプロジェクト、機能、起動を作成します。
  2. バックエンドアプリケーションコンテナ用の Amazon ECS タスクを作成し、そのタスクに AWS AppConfig エージェントコンテナをアタッチします。実行時に、アプリケーションコンテナは EvaluateFeature API を呼び出して機能フラグを取得します。Client-Side Evaluationがなければ、この API 呼び出しは Evidently クラウドサービスへのリモート呼び出しを実行します。
  3. Client-Side Evaluationでは、API 呼び出しはアプリケーションコンテナから localhost 上の AWS AppConfig エージェントコンテナに行われ、ネットワークのオーバーヘッドを短縮します。
  4. Evidentlyでは、お客様の AWS アカウント内の AWS AppConfigの設定 に Evidently の機能の同期コピーが保持されます。その後、機能に変更が加えられると、設定が更新されます。(通常は 1 分以内)
  5. バックエンドアプリケーションが初期化されると、エージェントは必要な設定プロファイルを取得してキャッシュし、定期的にポーリングしてキャッシュを更新します。AWS AppConfig エージェントがバックエンドアプリケーションから呼び出されると、キャッシュされたデータを使用してリクエストされた機能フラグを評価します。
  6. EvaluateFeature の呼び出しが成功するたびに、評価イベント と呼ばれるトランザクションレコードが生成されます。この便利なブックキーピングメカニズムは、ディベロッパーがデータを確認して、どのユーザーが、いつ、どの機能を見たかを知るのに役立ちます。評価イベントが生成されると、エージェント内のバッファに配置されます。バッファが特定のサイズまたは経過時間に達すると、バッファ内のイベントは PutProjectEvents API 経由で Evidently にアップロードされます。
  7. 評価イベントは、CloudWatch ログ、Amazon Simple Storage Service (Amazon S3)、CloudWatch メトリクスなど、ディベロッパーが設定したストレージでオフラインで分析できます。

ウォークスルー

Client-Side Evaluation を実証する実践的な例を見てみましょう。検索バーのあるシンプルなウェブページがあります。新しく、より洗練された検索バーを実装しましたが、図 2 のように既存の Web ページで問題が発生しないことを確認するために、訪問者の 10% にのみ表示したいと考えています。

Web page experience where 10% of users see the new search bar

図2. ユーザーの 10% が新しい検索バーを見ることができるウェブページエクスペリエンス

必要な AWS リソースは手動でセットアップすることもできますが、時間を節約するために事前に作成された AWS Cloud Development Kit (AWS CDK) の例を使用してみましょう。この例のサンプルコードは GitHub で入手できます。大まかな手順は次のとおりです。

  1. インフラストラクチャをプロビジョニングします。インフラストラクチャは次のもので構成されます。
    • バックエンドアプリケーションとして動作し、検索バーのバリエーションを返す Virtual Private Cloud (Amazon VPC) を備えた ECS サービス
    • 2つの検索バーにトラフィックを分割するためのEvidently の起動
  2. AWS AppConfig エージェントが Evidently のデータを取得する AWS AppConfig 環境
    ウェブページをテストします。コードがデプロイされたら、Client-Side Evaluationを使って機能フラグを取得するためにウェブページを訪問します。
  3. インフラストラクチャを削除してクリーンアップします。

前提条件

  • Git をインストールします。
  • Node と npm をインストールします。
  • AWS アカウント を作成します。
  • AWS CDK Toolkit をインストールします。AWS CDK Toolkit が最新バージョンに更新されていることを確認します。
  • Docker をインストールします。AWS CDKは、Dockerがインストールされていないと動作しません。

ステップ

リポジトリのクローン

まず、AWS CDK example の公式リポジトリをクローンします。

git clone https://github.com/aws-samples/aws-cdk-examples

リポジトリには、CDK で AWSインフラ を設定するための例が多数掲載されています。client-side evaluation の例に移動しましょう。

コードの説明

コードの例を見てみましょう。ウェブページにアクセスすると、リクエストは AWS Fargate にデプロイされたアプリケーションにルーティングされます。これにより、Elastic Compute Cloud (Amazon EC2) インスタンスを管理しなくても、ECS を使用してコンテナを直接実行できます。アプリケーションコードは Typescript の Node.js で記述され、Express フレームワークを利用しています。

<p><code>// local-image/app.ts</code></p><p><code>import * as express from 'express';</code><br /><code>import {Evidently} from '@aws-sdk/client-evidently';</code></p><p><code>const app = express();</code></p><p><code>const evidently = new Evidently({</code><br /><code>    endpoint: 'http://localhost:2772',</code><br /><code>    disableHostPrefix: true</code><br /><code>});</code></p><p><code>app.get("/", async (_, res) =&gt; {</code><br /><code>    try {</code><br /><code>        console.time('latency')</code><br /><code>        const evaluation = await evidently.evaluateFeature({</code><br /><code>            project: 'WebPage',</code><br /><code>            feature: 'SearchBar',</code><br /><code>            entityId: 'WebPageVisitor43'</code><br /><code>        })</code><br /><code>        console.timeEnd('latency')</code><br /><code>        res.send(evaluation.variation)</code><br /><code>    } catch (err: any) {</code><br /><code>        console.timeEnd('latency')</code><br /><code>        res.send(err.toString())</code><br /><code>    }</code><br /><code>});</code></p>

コンテナアプリケーションは AWS SDK for Javascript を使用して EvaluateFeature API を呼び出し、検索バーのバリエーション(古い検索バーまたは新しい検索バー)を返します。ここでは、操作のレイテンシーも記録します。EvaluateFeature リクエストは Evidently クライアント用に設定したエンドポイント http://localhost:2772 に転送されます。これは AWS AppConfig エージェントにアクセスできるローカルアドレスです。これを可能にするために、AWS AppConfig エージェントをコンテナとして Amazon ECS タスク定義 に追加します。

// index.ts

service.taskDefinition.addContainer('AppConfigAgent', {
    image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-appconfig/aws-appconfig-agent:2.x'),
    portMappings: [{
        containerPort: 2772
    }]
})

また、Evidentlyプロジェクト用に AppConfig のEnviroment をセットアップする必要があります。これは、プロジェクト内の機能の同期コピーを保持するための設定を作成する場所を Evidently に指示します。

// index.ts

const application = new appconfig.CfnApplication(this,'AppConfigApplication', {
    name: 'MyApplication'
});

const environment = new appconfig.CfnEnvironment(this, 'AppConfigEnvironment', {
    applicationId: application.ref,
    name: 'MyEnvironment'
});

const project = new evidently.CfnProject(this, 'EvidentlyProject', {
    name: 'WebPage',
    appConfigResource: {
        applicationId: application.ref,
        environmentId: environment.ref
    }
});

最後に、トラフィックの 10% だけが新しい検索バーを受信するように Evidently の機能と起動を設定します。

// index.ts

const launch = new evidently.CfnLaunch(this, 'EvidentlyLaunch', {
  project: project.name,
  name: 'MyLaunch',
  executionStatus: {
    status: 'START'
  },
  groups: [
    {
      feature: feature.name,
      variation: OLD_SEARCH_BAR,
      groupName: OLD_SEARCH_BAR
    },
    {
      feature: feature.name,
      variation: NEW_SEARCH_BAR,
      groupName: NEW_SEARCH_BAR
    }
  ],
  scheduledSplitsConfig: [{
    startTime: '2022-01-01T00:00:00Z',
    groupWeights: [
      {
        groupName: OLD_SEARCH_BAR,
        splitWeight: 90000
      },
      {
        groupName: NEW_SEARCH_BAR,
        splitWeight: 10000
      }
    ]
  }]
})

executionStatusSTART に設定し、startTime を過去のタイムスタンプに指定することで、すぐに起動を開始します。新しい検索バーが表示されるまで待ちたい場合は、将来の開始時間を指定できます。

依存関係のインストール

必要な Node modules をインストールします。

npm install

ビルドとデプロイ

ソースコードから AWS CDK テンプレートをビルドします。

npm run build

アプリをデプロイする前に

  1. ご使用の環境に AWS credentials を設定してください。
  2. The AWS CDK Toolkit は AWS アカウントにブートストラップされています。
  3. AWS アカウントの VPC 数が最大数に達していないことを確認してください。Amazon ECS サービスが Amazon VPC をデプロイします。

その後、AWS CDK テンプレートを AWS アカウントにデプロイできます。

cdk deploy

ウェブページのテスト

前の手順を実行すると、コンソールに次の出力が表示されます。

Console output showing a successful CDK deployment

図3. AWS CDK のデプロイが成功したことを示すコンソール出力

ブラウザで上記の FargateServiceServiceURL 出力で指定された URL にアクセスすると、oldSearchBar が表示されます。Amazon ECS タスクからの CloudWatch ログ にアクセスすると、アプリケーションログを確認できます。AWS コンソールに移動して CloudWatch ロググループページにアクセスし、EvidentlyClientSideEvaluationEcs というプレフィックスが付いたロググループにアクセスします。図4 のように、機能フラグの取得に 2ミリ秒もかかっていないことがわかります。

CloudWatch Logs for the Amazon ECS task showing an EvaluateFeature latency of 1.238 milliseconds

図 4. Amazon ECS タスクの CloudWatch ログに 1.238 ミリ秒の EvaluateFeature のレイテンシーが表示されます。

さらに、訪問者が検索バーの各バージョンをどのように見たかを確認できます。AWS コンソールで CloudWatch メトリクスのページにアクセスし、図 5 のように、All > Evidently > Feature, Project, Variation の下にある Evidently のメトリクスを確認します。

CloudWatch metrics showing the VariationCount: the number of times each feature flag variation was fetched

図 5. VariationCount (各機能フラグのバリエーションが取得された回数) を示す CloudWatch メトリクス

新しい検索バーが表示される訪問者の割合は、いつでも増減できます。AWS コンソールで、CloudWatch Evidently ページに移動し、Projects > WebPage > Launches > MyLaunch > Modify launch traffic に移動し、図 6 のように Traffic percentage を調整します。

Adjusting the traffic percentage of an Evidently launch

図 6. Evidently ローンチのトラフィックパーセンテージの調整

クリーンアップ

今後料金が発生しないように、リソースを削除してください。実行してみましょう。

cdk destroy

CloudFormation に移動すると、リソースが削除されたことを確認できます。

結論

このブログでは、Amazon CloudWatch Evidently の Client-Side Evaluation (クライアントサイドの評価) を使用してAmazon ECSでウェブページのバックエンドをセットアップする方法を学びました。サンプルの CloudFormation スタックは AWS CDK Toolkit で簡単にデプロイできました。次に、サンプルウェブページを見て、Client-Side Evaluation で機能フラグを取得する速度の向上を実演しました。Amazon ECS の代わりに AWS Lambda で Client-Side Evaluation を使用することに興味がある場合は、AWS CDK example をご覧ください。

Cole Thienes

Cole Thienes

Cole Thienes は Amazon CloudWatch のソフトウェアエンジニアです。彼はお客様がインフラストラクチャを監視し、アプリケーションを安全に管理するのに役立つソリューションの開発に注力しています。

翻訳はテクニカルアカウントマネージャーの日平が担当しました。原文はこちらです。