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](https://d2908q01vomqb2.cloudfront.net/b3f0c7f6bb763af1be91d9e74eabfeb199dc1f1f/2023/03/17/Picture1-2.jpg)
図1. Amazon CloudWatch Evidently の Client-Side Evaluationの高水準アーキテクチャ
- AWSコンソールのモバイルアプリケーション、API、または AWS CloudFormation を使用して、Evidently のプロジェクト、機能、起動を作成します。
- バックエンドアプリケーションコンテナ用の Amazon ECS タスクを作成し、そのタスクに AWS AppConfig エージェントコンテナをアタッチします。実行時に、アプリケーションコンテナは
EvaluateFeature
API を呼び出して機能フラグを取得します。Client-Side Evaluationがなければ、この API 呼び出しは Evidently クラウドサービスへのリモート呼び出しを実行します。 - Client-Side Evaluationでは、API 呼び出しはアプリケーションコンテナから
localhost
上の AWS AppConfig エージェントコンテナに行われ、ネットワークのオーバーヘッドを短縮します。 - Evidentlyでは、お客様の AWS アカウント内の AWS AppConfigの設定 に Evidently の機能の同期コピーが保持されます。その後、機能に変更が加えられると、設定が更新されます。(通常は 1 分以内)
- バックエンドアプリケーションが初期化されると、エージェントは必要な設定プロファイルを取得してキャッシュし、定期的にポーリングしてキャッシュを更新します。AWS AppConfig エージェントがバックエンドアプリケーションから呼び出されると、キャッシュされたデータを使用してリクエストされた機能フラグを評価します。
EvaluateFeature
の呼び出しが成功するたびに、評価イベント と呼ばれるトランザクションレコードが生成されます。この便利なブックキーピングメカニズムは、ディベロッパーがデータを確認して、どのユーザーが、いつ、どの機能を見たかを知るのに役立ちます。評価イベントが生成されると、エージェント内のバッファに配置されます。バッファが特定のサイズまたは経過時間に達すると、バッファ内のイベントはPutProjectEvents
API 経由で Evidently にアップロードされます。- 評価イベントは、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](https://d2908q01vomqb2.cloudfront.net/b3f0c7f6bb763af1be91d9e74eabfeb199dc1f1f/2023/03/17/2-2.jpg)
図2. ユーザーの 10% が新しい検索バーを見ることができるウェブページエクスペリエンス
必要な AWS リソースは手動でセットアップすることもできますが、時間を節約するために事前に作成された AWS Cloud Development Kit (AWS CDK) の例を使用してみましょう。この例のサンプルコードは GitHub で入手できます。大まかな手順は次のとおりです。
- インフラストラクチャをプロビジョニングします。インフラストラクチャは次のもので構成されます。
- バックエンドアプリケーションとして動作し、検索バーのバリエーションを返す Virtual Private Cloud (Amazon VPC) を備えた ECS サービス
- 2つの検索バーにトラフィックを分割するためのEvidently の起動
- AWS AppConfig エージェントが Evidently のデータを取得する AWS AppConfig 環境
ウェブページをテストします。コードがデプロイされたら、Client-Side Evaluationを使って機能フラグを取得するためにウェブページを訪問します。 - インフラストラクチャを削除してクリーンアップします。
前提条件
- 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) => {</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
}
]
}]
})
executionStatus
を START
に設定し、startTime
を過去のタイムスタンプに指定することで、すぐに起動を開始します。新しい検索バーが表示されるまで待ちたい場合は、将来の開始時間を指定できます。
依存関係のインストール
必要な Node modules をインストールします。
npm install
ビルドとデプロイ
ソースコードから AWS CDK テンプレートをビルドします。
npm run build
アプリをデプロイする前に
- ご使用の環境に AWS credentials を設定してください。
- The AWS CDK Toolkit は AWS アカウントにブートストラップされています。
- AWS アカウントの VPC 数が最大数に達していないことを確認してください。Amazon ECS サービスが Amazon VPC をデプロイします。
その後、AWS CDK テンプレートを AWS アカウントにデプロイできます。
cdk deploy
ウェブページのテスト
前の手順を実行すると、コンソールに次の出力が表示されます。
![Console output showing a successful CDK deployment](https://d2908q01vomqb2.cloudfront.net/b3f0c7f6bb763af1be91d9e74eabfeb199dc1f1f/2023/03/17/3-1.jpg)
図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](https://d2908q01vomqb2.cloudfront.net/b3f0c7f6bb763af1be91d9e74eabfeb199dc1f1f/2023/03/17/4.jpg)
図 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](https://d2908q01vomqb2.cloudfront.net/b3f0c7f6bb763af1be91d9e74eabfeb199dc1f1f/2023/03/17/5.jpg)
図 5. VariationCount (各機能フラグのバリエーションが取得された回数) を示す CloudWatch メトリクス
新しい検索バーが表示される訪問者の割合は、いつでも増減できます。AWS コンソールで、CloudWatch Evidently ページに移動し、Projects > WebPage > Launches > MyLaunch > Modify launch traffic に移動し、図 6 のように Traffic percentage を調整します。
![Adjusting the traffic percentage of an Evidently launch](https://d2908q01vomqb2.cloudfront.net/b3f0c7f6bb763af1be91d9e74eabfeb199dc1f1f/2023/03/17/6.jpg)
図 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 をご覧ください。
翻訳はテクニカルアカウントマネージャーの日平が担当しました。原文はこちらです。