このチュートリアルでは、Google Cloud サーバーレス テクノロジーを使用してウェブ パフォーマンス モニタリング アプリを作成する方法について説明します。
パフォーマンスは、ウェブアプリの成功に大きな役割を果たします。サイトのパフォーマンスが低いと、登録数の減少やユーザー維持率の低下を招く恐れがあります。その結果、ビジネス目標に影響する可能性もあります。ウェブアプリを設計、構築、テストするうえでは、パフォーマンスが重要な成功基準となります。
ただしアプリの進化とともに、ページのパフォーマンスも変わる可能性があります。デベロッパーによってイメージやスクリプトが追加または更新されることがあります。アプリ提供の基盤となるインフラストラクチャ自体が変わることもあります。したがって、ページのパフォーマンスを定期的にモニタリングすることが重要です。多くの方がパフォーマンス指標を保存して履歴分析を有効にしています。ページのパフォーマンスが定義済みのしきい値を下回った場合のアラート生成も、一般的に行われています。
目標
- Cloud ファンクションを作成し、ヘッドレス Chrome を使用してウェブページのパフォーマンス指標を収集します。
- 収集した指標を Cloud Storage に保存します。
- Cloud Storage 作成イベントによってトリガーされる別の Cloud Functions の関数を作成して、ページ指標を分析します。
- 分析結果を Firestore に保存します。
- Firestore 作成イベントによってトリガーされる別の Cloud Functions の関数を作成して、ページのパフォーマンスが低下した場合に、Pub/Sub にアラートをパブリッシュします。
- Cloud Scheduler のジョブを作成して、最初の Cloud Functions の関数を定期的にトリガーします。
- 成功シナリオと失敗シナリオの出力を検証します。
料金
このチュートリアルでは、Google Cloud の課金対象となる以下のコンポーネントを使用します。
- Cloud Functions
- Cloud Scheduler
- Cloud Storage
- Firestore
- Pub/Sub
- Container Registry
- Cloud Build
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。
始める前に
- Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build API を有効にします。
-
Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。
-
Cloud Functions, Cloud Scheduler, Pub/Sub, and Cloud Build API を有効にします。
アーキテクチャ
通常、ウェブ パフォーマンスのモニタリング オペレーションは生存期間が短くステートレスです。また、イベント ドリブンのオペレーションが多く、スケジュールに沿って発生するか、自動テスト パイプラインなど他のプロセスに付随してトリガーされます。こうした特性により、ウェブ解析アプリの実装にはサーバーレス アーキテクチャが好ましい選択肢であると言えます。
このチュートリアルでは、Cloud Functions、Firestore、Cloud Scheduler、Pub/Sub を含む、Google Cloud サーバーレス スタックのさまざまな部分を使用します。これらのサービスでは、インフラストラクチャの管理が不要で、料金は使用した分のみ発生します。アプリのコアは、Cloud Functions を使用して実装されます。Cloud Functions は、イベント ドリブンでスケーラブルなサーバーレスのランタイム環境です。Cloud Functions を使用すると、独立した疎結合ロジックを使ってアプリを作成、接続できます。
次の図は、このチュートリアルで作成するサーバーレス ソリューションのアーキテクチャを示しています。
環境の準備
サーバーレス環境を作成する前に、GitHub からコードを取得し、変数を設定して、後ほど行う分析と保存に必要なリソースを準備します。
コードの取得と環境変数の設定を行う
Google Cloud コンソールで Cloud Shell を開きます。
このチュートリアルで使用する Cloud Functions のコードを含む、リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/solutions-serverless-web-monitoring.git
Cloud Functions のディレクトリを変更します。
cd solutions-serverless-web-monitoring/functions
現在のプロジェクト ID とプロジェクト番号を、シェル変数として設定します。
export PROJECT=$DEVSHELL_PROJECT_ID export PROJECT_NUM=$(gcloud projects list \ --filter="$PROJECT" \ --format="value(PROJECT_NUMBER)")
Cloud Functions のデフォルトのデプロイ リージョンを設定します。次の例では、リージョンは
us-east1
に設定されていますが、Cloud Functions が利用可能な任意のリージョンに変更できます。export REGION=us-east1 gcloud config set functions/region $REGION
Cloud Storage バケットを作成する
このセクションでは、Cloud Storage バケットを作成して、収集されたページ パフォーマンス データを保存します。任意のロケーションまたはストレージ クラスを選択できますが、バケットを使用する Cloud Functions と同じ場所に、バケットを作成することをおすすめします。
Cloud Shell に、指標を保存する Cloud Storage バケットの名前のシェル変数をエクスポートします。バケット名は、グローバルに一意である必要があるため、以下のコマンドでは Google Cloud プロジェクト番号をバケット名のサフィックスとして使用します。
export METRICS_BUCKET=page-metrics-$PROJECT_NUM
gsutil
ツールを使用して、バケットを作成します。gsutil mb -l $REGION gs://$METRICS_BUCKET
バケット名で
env-vars.yaml
ファイルを更新します。後で、このファイルに含まれる環境変数を Cloud Functions に渡します。sed -i "s/\[YOUR_METRICS_BUCKET\]/$METRICS_BUCKET/" env-vars.yaml
Firestore コレクションを作成する
ページ パフォーマンス指標の分析は、後のセクションで行います。このセクションでは、Firestore コレクションを作成して、それぞれの分析結果を保存します。
Google Cloud コンソールで、[Firestore] ページに移動します。
Firestore データベースを作成したことがない場合は、次の手順を行います。
- [ネイティブ モードを選択] をクリックして、Firestore を有効にします。
- Cloud Functions を実行するリージョンに近いリージョンのロケーションを選択します。
- [データベースを作成] をクリックします。
構成が完了するまで、少し時間がかかります。
[コレクションを開始] をクリックして、
page-metrics
にコレクション ID を設定します。[保存] をクリックします。
Pub/Sub トピックとサブスクリプションを作成する
分析によりページのパフォーマンス低下が判明した場合、関連システムと関係者に通知するのが一般的です。このセクションでは、パフォーマンスの低下に関するメッセージを含む Pub/Sub トピックを作成します。
Cloud Shell で、
performance-alerts
という名前の Pub/Sub トピックを作成します。gcloud pubsub topics create performance-alerts
トピックのサブスクリプションを作成します。作成したサブスクリプションを使用して、トピックにアラート メッセージがパブリッシュされていることを確認します。
gcloud pubsub subscriptions create performance-alerts-sub \ --topic performance-alerts
ページ パフォーマンス指標の収集
多くのウェブサイトでは、JavaScript を使用してページのコンテンツを動的にレンダリングします。その結果、パフォーマンス分析はより複雑になります。これは、クライアントが、ウェブページを完全に読み込むためにブラウザをエミュレートする必要があるためです。Cloud Functions の Node.js ランタイムは、ヘッドレス Chrome をサポートします。これは、サーバーレス環境で、完全なウェブブラウザの機能を提供します。
Puppeteer は、Chrome DevTools チームが構築した Node.js ライブラリで、ヘッドレス Chrome を制御する高レベルの API を提供します。デフォルトでは、Puppeteer は、最新バージョンのブラウザをライブラリとともにインストールします。そのため、Puppeteer を Cloud ファンクションの依存関係に追加できます。これはヘッドレス Chrome をこのファンクション内で使用する簡単な方法です。
ウェブページのパフォーマンスの測定と分析は、広範かつ複雑な分野です。簡単に行えるように、このチュートリアルでは Puppeteer を使用して、トップレベルのページ パフォーマンス指標を収集します。ただし、Puppeteer と Chrome DevTools Protocol(CDP)を使用して、タイムライン トレースなどの、より詳細な情報も収集できます。また、ネットワークの輻輳をエミュレートし、CPU スロットリングを実行することで、エンドユーザー エクスペリエンスをより適切に再現できます。ウェブページのパフォーマンス分析を初めて導入する場合は、Chrome のウェブ デベロッパー向けサイトを参考にしてください。
ウェブページの読み込み時間は、クライアントのパフォーマンス特性など、多くの要因の影響を受けますので注意してください。Cloud Functions の関数の CPU および RAM 構成を使用して、ベースラインを確立することが重要です。
以下の tracer/index.js
ファイルからのスニペットは、Puppeteer を使用してウェブページを読み込む方法を示しています。
Cloud Shell で、Cloud Functions の
trace
関数をデプロイします。gcloud functions deploy trace \ --trigger-http \ --runtime nodejs10 \ --memory 1GB \ --source tracer \ --env-vars-file env-vars.yaml \ --quiet
Cloud Functions の関数のデプロイには数分かかる場合があります。
デプロイ パラメータでは、この関数には HTTP トリガー、Node.js 10 ランタイムの使用、1 GB のメモリが必要であることが指定されます。このメモリ量は、ヘッドレス Chrome の実行に必要です。環境変数は
env-vars.yaml
ファイルを使用して、関数に渡されます。
デフォルトでは、HTTP にトリガーされる Cloud Functions は、未認証の呼び出しを許可します。そのため、トレース機能を保護する必要があります。
allUsers
のcloudfunctions.invoker
IAM ロールを削除します。gcloud beta functions remove-iam-policy-binding trace \ --member allUsers \ --role roles/cloudfunctions.invoker
指標の分析
通常、ウェブ パフォーマンス モニタリングの実施目標は、定義済みのベンチマークに照らしてパフォーマンスを追跡することです。特定の指標が予想されるしきい値を超える場合、最近のソフトウェア リリースか、基盤となるインフラストラクチャに問題がある可能性があります。
このセクションでは、Python で Cloud Functions の関数を作成してページ指標を解析し、結果を Firestore コレクションに保存します。この関数は、予想されるしきい値に照らして FirstMeaningfulPaint
指標を評価し、しきい値を超えた場合には分析結果に問題があるとしてマークします。FirstMeaningfulPaint
はユーザー セントリックの指標で、ページがユーザーにとって有用になるタイミングを大まかに示します。指標を含むバケットに新しいファイルが書き込まれるたび、Cloud Storage トリガーを使用して analyze 関数を実行します。
以下の analyzer/main.py
ファイルからのスニペットは、この関数のロジックを示しています。
Cloud Functions の
analyze
関数をデプロイします。gcloud functions deploy analyze \ --trigger-resource gs://$METRICS_BUCKET \ --trigger-event google.storage.object.finalize \ --runtime python37 \ --source analyzer \ --env-vars-file env-vars.yaml
この関数は、指標バケット内の
finalize
イベントによってトリガーされます。これは、バケット内にオブジェクトが作成されるたびに送信されます。この関数は、Python 3.7 ランタイムを使用します。
失敗時のアラート
指標分析によってパフォーマンスの低いページが示された場合は、措置を講じるのが一般的です。
このセクションでは、ページ パフォーマンスが不十分な場合に Cloud 関数を作成して、Pub/Sub トピックにメッセージを送信します。この関数は、Firestore コレクションでドキュメントが作成されるたびにトリガーされます。関係者は、Pub/Sub トピックをサブスクライブして、適切な措置を講じることができます。たとえば、サポートアプリで Pub/Sub メッセージをサブスクライブしてメールを送信できます。サポート ページャーやバグを開くこともできます。
以下の alerter/main.py
ファイルからのスニペットは、この関数のロジックを示しています。
ステータスのフィールドが失敗を示す場合にのみ、アラートが送信されることに注意してください。
Cloud Functions の
alert
関数をデプロイします。gcloud functions deploy alert \ --trigger-event providers/cloud.firestore/eventTypes/document.create \ --trigger-resource "projects/$PROJECT/databases/(default)/documents/page-metrics/{any}" \ --runtime python37 \ --source alerter \ --env-vars-file env-vars.yaml \ --entry-point generate_alert
この関数は、
page-metrics
Cloud Firestore コレクション内で、document.create
イベントによってトリガーされます。{any}
サフィックスは、コレクション内でドキュメントが作成されるたび、関数がトリガーされることを示すワイルドカードです。
分析のスケジューリング
ページのパフォーマンスは、定期的にモニタリングすることをおすすめします。たとえば、特定のページを 1 時間ごと、毎日、または毎週分析したいとします。このセクションでは、Cloud Scheduler のジョブを作成して、定期的に trace
関数をトリガーし、分析パイプラインを実行します。
Cloud Scheduler のジョブは、trace
関数に必要な cloudfunctions.invoker
IAM ロールが付与されたサービス アカウントを使用して実行されます。
ウェブページが正しく応答しない場合や、リクエストのタイムアウトが発生した場合、ウェブ解析アプリでの再試行は避けられません。そのため、アプリに再試行ロジックを実装することが重要です。Cloud Functions では、バックグラウンド関数の再試行をサポートしています。
HTTP トリガータイプの Cloud Functions の関数では再試行ができないため、Cloud Functions を使用して trace
関数を再試行することはできません。ただし、Cloud Scheduler は再試行をサポートしています。再試行パラメータの構成の詳細については、RetryConfig のドキュメントを参照してください。
3 つの Cloud Functions 関数が正しくデプロイされ、
ACTIVE
ステータスが表示されていることを確認します。gcloud functions list
Cloud Scheduler のジョブを実行するための ID として使用する新しいサービス アカウントを作成します。
gcloud iam service-accounts create tracer-job-sa
新しいサービス アカウントに
trace
関数のcloudfunctions.invoker
IAM ロールを付与します。gcloud beta functions add-iam-policy-binding trace \ --role roles/cloudfunctions.invoker \ --member "serviceAccount:tracer-job-sa@$PROJECT.iam.gserviceaccount.com"
Cloud Scheduler のジョブを作成します。
gcloud scheduler jobs create http traceWithRetry \ --uri="https://$REGION-$PROJECT.cloudfunctions.net/trace" \ --http-method=POST \ --message-body="{\"url\":\"http://www.example.com\"}" \ --headers="Content-Type=application/json" \ --oidc-service-account-email="tracer-job-sa@$PROJECT.iam.gserviceaccount.com" \ --schedule="0 3 * * *" \ --time-zone="UTC" \ --max-retry-attempts=3 \ --min-backoff=30s
このジョブでは、HTTP トリガーの
trace
関数が呼び出されます。そのため、コマンドはジョブタイプをhttp
として指定し、関数トリガー URL をuri
値として提供します。分析対象ページ(この場合はwww.example.com
)は、message-body
フラグで提供されます。oidc-service-account-email
フラグによって、認証に使用するサービス アカウントが定義されます。このコマンドはmax-retry-attempts
フラグを使用して行われた再試行回数を示します。また、schedule
フラグで渡された値によって、毎日午前 3 時(UTC)に実行スケジュールが設定されます。
結果の検証
このセクションでは、成功条件と失敗条件の両方で、想定された挙動が得られることを確認します。
成功を検証する
Cloud Scheduler のジョブは、次のスケジュールされた時間(この場合は午前 3 時(UTC))まで実行しません。すぐに結果を得るためには、手動で実行をトリガーできます。
- Cloud Scheduler のジョブの初期化が完了するまで、90 秒待ちます。
Cloud Scheduler のジョブを手動で実行します。
gcloud scheduler jobs run traceWithRetry
関数パイプラインが完了するまで、約 30 秒待ちます。
指標バケットの内容を一覧表示して、ページ指標が収集されたことを確認します。
gsutil ls -l gs://$METRICS_BUCKET
Google Cloud コンソールで、Cloud Logging ビューアのページを開きます。
3 つの Cloud Functions(
trace
、analyze
、alert
)それぞれのログメッセージが表示されます。ログの出力に時間がかかることがあるため、必要に応じて [ログ] ペインを更新してください。Firestore ドキュメント ID をメモしておきます。これは、「
Created new Firestore document page-metrics/
」という文字列の後に表示されます。Google Cloud コンソールで、[Firestore] ページに移動します。
分析結果を含むドキュメントを調べます。ドキュメントの値は
PASS
ステータスを示し、最新のページ パフォーマンス指標が含まれます。Cloud Shell で、サブスクリプションからメッセージを pull して、Pub/Sub トピックにアラート メッセージが送信されていないことを確認します。
gcloud pubsub subscriptions pull \ projects/$PROJECT/subscriptions/performance-alerts-sub \ --auto-ack
リストにアラート メッセージがないことがわかります。
失敗を検証する
trace 関数を手動でトリガーします。今回は、Google Cloud チュートリアルのページを URL として提供します。このページには多くの動的コンテンツがあり、ページの読み込み時間を、想定された最大しきい値を超えて増大させます。
gcloud functions call trace \ --data='{"url":"https://cloud.google.com/docs/tutorials"}'
プロジェクトには
Owner
またはEditor
IAM ロールがあるため、関数を呼び出すための十分な権限があります。関数パイプラインが完了するまで、約 30 秒待ちます。
指標バケットの内容を一覧表示して、追加の指標が収集されたことを確認します。
gsutil ls -l gs://$METRICS_BUCKET
各バケットに、2 つのアイテムが表示されます。
Google Cloud コンソールで、Cloud Logging ビューアのページに移動し、Cloud Functions のログをフィルタします。
ページの読み込み時間が最大許容値を超えたことを示すエラーが、
analyze
関数から表示されます。この場合も、[ログ] ペインを更新して、最新メッセージを表示する必要が生じる可能性があります。Firestore のドキュメント ID をメモします。
Google Cloud コンソールで、[Firestore] ページに移動します。
失敗した分析を記述したドキュメントを見つけます。
ステータスのフィールドに
FAIL
とマークされています。Cloud Shell で、サブスクリプションからメッセージを pull して、Pub/Sub トピックにアラート メッセージが送信されたことを確認します。
gcloud pubsub subscriptions pull \ projects/$PROJECT/subscriptions/performance-alerts-sub \ --auto-ack
この場合、メッセージの内容が表示されます。
クリーンアップ
プロジェクトの削除
- Google Cloud コンソールで、[リソースの管理] ページに移動します。
- プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
- ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。
次のステップ
- Google Cloud サーバーレス テクノロジーの詳細を確認する。
- 他の Cloud Functions のチュートリアルを確認する。
- Puppeteer とヘッドレス Chrome のその他の使用法について説明する、Google I/O 2018 の動画を見る。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センター をご覧ください。