arrow_back

Cloud Run と Pub/Sub を使用して復元性に優れた非同期システムをビルドする

参加 ログイン
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

Cloud Run と Pub/Sub を使用して復元性に優れた非同期システムをビルドする

Lab 1時間 universal_currency_alt クレジット: 5 show_chart 中級
Test and share your knowledge with our community!
done
Get access to over 700 hands-on labs, skill badges, and courses

GSP650

Google Cloud セルフペース ラボ

Pet Theory のロゴ

概要

「Google Cloud Serverless Workshop: Pet Theory」クエストのラボでは、架空のビジネス シナリオの登場人物を支援してサーバーレスへの移行計画を進めていきます。

Lily さんは 12 年前、獣医クリニック チェーン「Pet Theory」を開業しました。年を追うごとにクリニックの数は増え続け、自動化が必要になりました。Pet Theory では、試験室から戻ってきた医学的検査の結果の処理に時間がかかっており、ミスも増えているので、Lily さんはこの状態を改善したいと思っています。

現在、Pet Theory の IT 管理者である Patrick さんは手作業で検査結果を処理しています。検査結果が戻ってくると、検査したペットの飼い主にメールを作成して送信します。その後、スマートフォンでテキスト メッセージを打ち、テキストとして結果を飼い主に送っています。

Patrick さんはソフトウェア コンサルタントの Ruby さんと協力し、よりスケーラブルなシステムを設計しようとしています。多くの継続的なメンテナンスを必要としないソリューションを構築したいと考えた Patrick さんと Ruby さんは、サーバーレス テクノロジーを採用することにしました。

前提条件

Cloud コンソールとシェル環境に精通していることを前提としています。このラボは、シリーズの一部です。次のような先行のラボを受講していれば役立ちますが、必須ではありません。

ファイルの編集にも慣れている必要があります。ご自身で使い慣れたテキスト エディタ(nanovi など)を使用するか、上部のリボンにある Cloud Shell からコードエディタを起動できます。

Cloud Shell コードエディタ アイコン

設定と要件

注: このラボでは、Username 1 として Google Cloud コンソールにログインしてください。そうしないと、ラボの実施中にエラーが発生します。

[ラボを開始] ボタンをクリックする前に

こちらの手順をお読みください。ラボの時間は記録されており、一時停止することはできません。[ラボを開始] をクリックするとスタートするタイマーは、Google Cloud のリソースを利用できる時間を示しています。

このハンズオンラボでは、シミュレーションやデモ環境ではなく、実際のクラウド環境を使ってご自身でラボのアクティビティを行うことができます。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。

このラボを完了するためには、下記が必要です。

  • 標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モードまたはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生することを防ぎます。
  • ラボを完了するために十分な時間を確保してください。ラボをいったん開始すると一時停止することはできません。
注: すでに個人の Google Cloud アカウントやプロジェクトをお持ちの場合でも、このラボでは使用しないでください。アカウントへの追加料金が発生する可能性があります。

ラボを開始して Google Cloud コンソールにログインする方法

  1. [ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるポップアップでお支払い方法を選択してください。 左側の [ラボの詳細] パネルには、以下が表示されます。

    • [Google コンソールを開く] ボタン
    • 残り時間
    • このラボで使用する必要がある一時的な認証情報
    • このラボを行うために必要なその他の情報(ある場合)
  2. [Google コンソールを開く] をクリックします。 ラボでリソースが起動し、別のタブで [ログイン] ページが表示されます。

    ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。

    注: [アカウントの選択] ダイアログが表示されたら、[別のアカウントを使用] をクリックします。
  3. 必要に応じて、[ラボの詳細] パネルから [ユーザー名] をコピーして [ログイン] ダイアログに貼り付けます。[次へ] をクリックします。

  4. [ラボの詳細] パネルから [パスワード] をコピーして [ようこそ] ダイアログに貼り付けます。[次へ] をクリックします。

    重要: 認証情報は左側のパネルに表示されたものを使用してください。Google Cloud Skills Boost の認証情報は使用しないでください。 注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
  5. その後次のように進みます。

    • 利用規約に同意してください。
    • 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
    • 無料トライアルには登録しないでください。

その後このタブで Cloud Console が開きます。

注: 左上にある [ナビゲーション メニュー] をクリックすると、Google Cloud のプロダクトやサービスのリストが含まれるメニューが表示されます。 ナビゲーション メニュー アイコン

Cloud Shell をアクティブにする

Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。

  1. Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン 「Cloud Shell をアクティブにする」アイコン をクリックします。

接続した時点で認証が完了しており、プロジェクトに各自の PROJECT_ID が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。

Your Cloud Platform project in this session is set to YOUR_PROJECT_ID

gcloud は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。

  1. (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
  1. [承認] をクリックします。

  2. 出力は次のようになります。

出力:

ACTIVE: * ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project

出力:

[core] project = <project_ID>

出力例:

[core] project = qwiklabs-gcp-44776a13dea667a6 注: Google Cloud における gcloud ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。

リージョンとゾーンを設定する

一部の Compute Engine リソースは、リージョン内やゾーン内に存在します。リージョンとは、リソースを実行できる特定の地理的な場所です。1 つのリージョンには 1 つ以上のゾーンがあります。

Cloud コンソールで次の gcloud コマンドを実行して、ラボのデフォルトのリージョンとゾーンを設定します。

gcloud config set compute/zone "{{{project_0.default_zone|ZONE}}}" export ZONE=$(gcloud config get compute/zone) gcloud config set compute/region "{{{project_0.default_region|REGION}}}" export REGION=$(gcloud config get compute/region)

シナリオ

Pet Theory では、飼い主に検査結果を伝えるプロセスを自動化したいと考えています。予約が増えて対応が難しくなっていたので、Lily さんは Ruby さんに助けを求めることにしました。

Lily

Lily さん(Pet Theory の創業者)

Ruby さん、お世話になっております。

先日は保険ポータルを整理していただきありがとうございました。

さて、この度は医学的検査の結果についてお手伝いいただけないかと考えています。もっと効率的に飼い主さんに結果を送りたいのです。

Lily

Ruby

Ruby さん(ソフトウェア コンサルタント)

Lily さん、ご連絡ありがとうございます。

わかりました。現状を改善できそうなアイデアがいくつかありますので、検討したいと思います。

Ruby

タスク 1. アーキテクチャ

Pet Theory では、外部の検査会社を利用して医学的検査を実施しています。検査会社で医学的検査が終わると、結果が Pet Theory に送られます。

検査会社では、HTTP(S) POST を使用して Pet Theory のウェブ エンドポイントに接続し、医学的検査の結果を送信しています。次の図に、全般的なアーキテクチャの概要を示します。

Pet Theory のシステム アーキテクチャ図

Ruby さんは、既存のプロセス全体を確認し、以下の処理が可能なシステムを設計できると考えました。

  1. HTTP POST リクエストを受信し、受信確認を検査の試験室に送ります。
  2. 飼い主に検査結果をメールで送ります。
  3. 飼い主に検査結果をテキスト メッセージ(SMS)とメールで送ります。

Ruby さんは上記の各アクティビティを分離する設計にしたため、以下の要素が必要になりました。

  • 検査結果のリクエストとレスポンスを実行するサービス
  • 飼い主に検査結果をメールで送るサービス
  • 飼い主にテキスト メッセージ(SMS)を送るサービス
  • サービス間の通信に使用する Pub/Sub
  • アプリケーション アーキテクチャとして使用するサーバーレス インフラストラクチャ

Ruby さんは、単一用途の関数を使用することで、記述しやすくバグの少ないコードの開発を目指しています。

Ruby

Ruby さん(ソフトウェア コンサルタント)

Patrick さん、お世話になっております。

Lily さんから検査記録を処理するプロトタイプを作成するよう依頼がありました。

まず、new-lab-report という名前の Pub/Sub トピックを設定していただけますでしょうか。

Ruby

Patrick

Patrick さん(IT 管理者)

Ruby さん、ご連絡ありがとうございます。

素晴らしいプロジェクトですね。どちらも Google Cloud ですぐに設定できる作業ですので、今朝のうちに終わらせようと思います。

Patrick

Pub/Sub トピックの作成

Patrick さんが new-lab-report という Pub/Sub トピックを作成するお手伝いをしましょう。

Cloud Pub/Sub がハイライト表示されたアーキテクチャ図

サービスが Pub/Sub メッセージをパブリッシュする際、メッセージにトピックをタグ付けする必要があります。ここで作成されるサービスが、検査報告書を取得し、見つかった各報告書に対してメッセージをパブリッシュします。

まず、このタスクで使用するトピックを作成する必要があります。

  1. 次のコマンドを実行して、Pub/Sub トピックを作成します。
gcloud pubsub topics create new-lab-report

トピック「new-lab-report」にサブスクライブした任意のサービスは、検査報告書サービスがパブリッシュするメッセージを取得できます。上記の図には、このようにメッセージを取得するサービスとして、メールサービスと SMS サービスの 2 つが示されています。

  1. その後、クラウドでコードを実行する Cloud Run を有効にします。
gcloud services enable run.googleapis.com

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

Pub/Sub トピックの作成

Pub/Sub トピックの準備ができたことを Ruby さんに伝えましょう。

Patrick

Patrick さん(IT 管理者)

Ruby さん、お世話になっております。

作業が終わりました。

お手数でなければ、このプロトタイプがどのような形になるか知りたいです。一緒に作業していただくことはできますか。

Patrick

Ruby

Ruby さん(ソフトウェア コンサルタント)

Patrick さん、ご連絡ありがとうございます。

迅速に対応していただきありがとうございました。時間を作りますので、一緒に作成作業を進めましょう。

Ruby

タスク 2. 検査報告書サービスのビルド

Ruby さんが新しい検査報告書サービスを設定するお手伝いをしましょう。

検査報告書サービスがハイライト表示されたアーキテクチャ図

このサービスはプロトタイピング用なので、機能は次の 2 つのみとします。

  1. 報告書のデータを含む検査報告書の HTTPS POST を受信する
  2. Pub/Sub にメッセージをパブリッシュする

検査報告書サービス用のコードの追加

  1. Cloud Shell に戻り、このラボに必要なリポジトリのクローンを作成します。
git clone https://github.com/rosera/pet-theory.git
  1. lab-service ディレクトリに移動します。
cd pet-theory/lab05/lab-service
  1. HTTPS リクエストを受信し、Pub/Sub にパブリッシュするのに必要な以下のパッケージをインストールします。
npm install express npm install body-parser npm install @google-cloud/pubsub

これらのコマンドにより package.json ファイルが更新され、このサービスに必要な依存関係が示されます。

Cloud Run にコードをどのように開始するかを指示できるよう、package.json ファイルを編集します。

  1. package.json ファイルを開きます。

  2. package.json ファイル 7 行目の scripts セクションに、コード行 "start": "node index.js", を以下のように追加して、ファイルを保存します。

"scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, 注: コードは以下に示すとおりに最後のカンマまで含めて追加してください。

"start": "node index.js",

そうしないと、デプロイ中にエラーが発生します。
  1. index.js という名前の新しいファイルを作成して、次のコードを追加します。
const {PubSub} = require('@google-cloud/pubsub'); const pubsub = new PubSub(); const express = require('express'); const app = express(); const bodyParser = require('body-parser'); app.use(bodyParser.json()); const port = process.env.PORT || 8080; app.listen(port, () => { console.log('Listening on port', port); }); app.post('/', async (req, res) => { try { const labReport = req.body; await publishPubSubMessage(labReport); res.status(204).send(); } catch (ex) { console.log(ex); res.status(500).send(ex); } }) async function publishPubSubMessage(labReport) { const buffer = Buffer.from(JSON.stringify(labReport)); await pubsub.topic('new-lab-report').publish(buffer); } 次の 2 行でサービスの主な処理が行われます。

const labReport = req.body;

await publishPubSubMessage(labReport);

具体的な処理内容は以下のとおりです。

  • POST リクエストから検査報告書を抽出します。
  • 新たに POST で送信された検査報告書を含む Pub/Sub メッセージをパブリッシュします。
  1. 次に、Dockerfile という名前のファイルを作成して、以下のコードを追加します。
FROM node:18 WORKDIR /usr/src/app COPY package.json package*.json ./ RUN npm install --only=production COPY . . CMD [ "npm", "start" ]

このファイルで、Cloud Run サービスをコンテナにパッケージ化する方法を定義します。

lab-report-service のデプロイ

  1. deploy.sh という名前のファイルを作成して、次のコマンドを貼り付けます。
gcloud builds submit \ --tag gcr.io/$GOOGLE_CLOUD_PROJECT/lab-report-service gcloud run deploy lab-report-service \ --image gcr.io/$GOOGLE_CLOUD_PROJECT/lab-report-service \ --platform managed \ --region {{{project_0.default_region | "REGION"}}} \ --allow-unauthenticated \ --max-instances=1
  1. Cloud Shell で、次のコマンドを実行して、このファイルを実行可能にします。
chmod u+x deploy.sh
  1. では、検査報告書サービスをデプロイします。次のようにデプロイ スクリプトを実行します。
./deploy.sh

タイミングにより、このコマンドを最初に実行したときにエラーが表示される場合があります。その場合は、deploy.sh を再実行します。

デプロイが正常に完了したら、以下のようなメッセージが表示されます。

Service [lab-report-service] revision [lab-report-service-00001] has been deployed and is serving traffic at https://lab-report-service-[hash].a.run.app

検査報告書サービスがデプロイされ、HTTP 経由で医学的検査の結果を取得できるようになりました。これで、新しいサービスが稼働しているかをテストできます。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

検査報告書サービスのデプロイ: ビルド

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

検査報告書サービスのデプロイ: リビジョンの作成

検査報告書サービスのテスト

検査報告書サービスを検証するために、検査会社から送信される 3 件の HTTPS POST をシミュレートします。これら 3 件の POST には、それぞれ 1 つの検査報告書が含まれています。テストでは、作成する検査報告書に ID のみを含めます。

  1. まず、検査報告書サービスへの URL を環境変数に設定し、使用しやすくします。
export LAB_REPORT_SERVICE_URL=$(gcloud run services describe lab-report-service --platform managed --region {{{project_0.default_region | "REGION"}}} --format="value(status.address.url)")
  1. LAB_REPORT_SERVICE_URL が正しく取得されたことを確認します。
echo $LAB_REPORT_SERVICE_URL
  1. post-reports.sh という名前の新しいファイルを作成して、以下のコードを追加します。
curl -X POST \ -H "Content-Type: application/json" \ -d "{\"id\": 12}" \ $LAB_REPORT_SERVICE_URL & curl -X POST \ -H "Content-Type: application/json" \ -d "{\"id\": 34}" \ $LAB_REPORT_SERVICE_URL & curl -X POST \ -H "Content-Type: application/json" \ -d "{\"id\": 56}" \ $LAB_REPORT_SERVICE_URL &

上記のスクリプトでは、curl コマンドを使用して、検査報告書サービスの URL に 3 つの異なる ID を POST で送信します。各コマンドはバックグラウンドで個別に実行されます。

  1. post-reports.sh スクリプトを実行可能にします。
chmod u+x post-reports.sh
  1. 上記のスクリプトを使用して 3 件の検査報告書を POST で送信し、検査報告書サービスのエンドポイントをテストします。
./post-reports.sh

このスクリプトによって、検査報告書サービスに 3 件の検査報告書が POST で送信されました。ログで結果を確認します。

  1. Cloud コンソールでナビゲーション メニュー(ナビゲーション メニュー アイコン)> [Cloud Run] をクリックします。

  2. 新しくデプロイした lab-report-service が [サービス] のリストに表示されたら、これをクリックします。

  3. 次のページに、lab-report-service の詳細が表示されます。[ログ] タブをクリックします。

[ログ] ページには、先ほどスクリプトを使用して POST で送信した 3 件の検査報告書の結果が表示されます。以下のように、OK を意味する HTTP コード 204(No Content)が返されると成功です。エントリが表示されない場合は、右側にあるスクロールバーを上下に動かします。これにより、ログが再読み込みされます。

ログの結果

次に、SMS とメールのサービスを記述します。これらのサービスは、検査報告書サービスが「new-lab-report」トピックに Pub/Sub メッセージをパブリッシュしたときにトリガーされます。

タスク 3. メールサービス

Ruby さんが新しいメールサービスを設定するお手伝いをしましょう。

メールサービスがハイライト表示されたアーキテクチャ図

メールサービス用のコードの追加

  1. メールサービスのディレクトリに移動します。
cd ~/pet-theory/lab05/email-service
  1. 受信する HTTPS リクエストをコードで処理できるように、以下のパッケージをインストールします。
npm install express npm install body-parser

上記のコマンドは、アプリケーションとその依存関係を記述する package.json ファイルを更新します。start 命令を追加して Cloud Run にコードの実行方法を指示します。

  1. package.json ファイルを開きます。

  2. scripts セクションに以下のように "start": "node index.js", の行を追加して、ファイルを保存します。

"scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, 注: コードは以下に示すとおりに最後のカンマまで含めて追加してください。

"start": "node index.js",

そうしないと、デプロイ中にエラーが発生します。
  1. index.js という名前の新しいファイルを作成して、以下のコードを追加します。
const express = require('express'); const app = express(); const bodyParser = require('body-parser'); app.use(bodyParser.json()); const port = process.env.PORT || 8080; app.listen(port, () => { console.log('Listening on port', port); }); app.post('/', async (req, res) => { const labReport = decodeBase64Json(req.body.message.data); try { console.log(`Email Service: Report ${labReport.id} trying...`); sendEmail(); console.log(`Email Service: Report ${labReport.id} success :-)`); res.status(204).send(); } catch (ex) { console.log(`Email Service: Report ${labReport.id} failure: ${ex}`); res.status(500).send(); } }) function decodeBase64Json(data) { return JSON.parse(Buffer.from(data, 'base64').toString()); } function sendEmail() { console.log('Sending email'); }

このコードは、Pub/Sub がメッセージをサービスに POST で送信したときに実行され、以下の処理を行います。

  • Pub/Sub メッセージを解読し、sendEmail() 関数の呼び出しを試みます。
  • 呼び出しに成功し、例外がスローされなければ、ステータス コード 204 を返し、メッセージが処理されたことを Pub/Sub に通知します。
  • 例外が発生した場合、サービスはステータス コード 500 を返し、メッセージが処理されなかったことを Pub/Sub に通知します。Pub/Sub は、後でサービスにもう一度メッセージを配信する必要があります。

サービス間の通信が正常に動作していることを確認した後、Ruby さんは sendEmail() 関数にコードを追加して、実際にメールを送信します。

  1. 次に、Dockerfile という名前のファイルを作成して、以下のコードを追加します。
FROM node:18 WORKDIR /usr/src/app COPY package.json package*.json ./ RUN npm install --only=production COPY . . CMD [ "npm", "start" ]

このファイルで、Cloud Run サービスをコンテナにパッケージ化する方法を定義します。

メールサービスのデプロイ

  1. deploy.sh という名前の新しいファイルを作成して、以下のコードを追加します。
gcloud builds submit \ --tag gcr.io/$GOOGLE_CLOUD_PROJECT/email-service gcloud run deploy email-service \ --image gcr.io/$GOOGLE_CLOUD_PROJECT/email-service \ --platform managed \ --region {{{project_0.default_region | "REGION"}}} \ --no-allow-unauthenticated \ --max-instances=1
  1. deploy.sh を実行可能にします。
chmod u+x deploy.sh
  1. メールサービスをデプロイします。
./deploy.sh

デプロイが完了したら、以下のようなメッセージが表示されます。

Service [email-service] revision [email-service-00001] has been deployed and is serving traffic at https://email-service-[hash].a.run.app

サービスが正常にデプロイされました。Pub/Sub メッセージが配信されたときにメールサービスがトリガーされることを確認する必要があります。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

メールサービスのデプロイ: ビルド

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

メールサービスのデプロイ: リビジョンの作成

Pub/Sub にメールサービスをトリガーさせるための構成

「new-lab-report」トピックを使用して新しい Pub/Sub メッセージがパブリッシュされたときに、メールサービスをトリガーする必要があります。このためには、このサービスに関連するリクエストを自動的に処理するようサービス アカウントを構成します。

Cloud Pub/Sub からメールサービスへのフローがハイライト表示されたアーキテクチャ図

  1. Pub/Sub メッセージに反応してサービスをトリガーするのに使用する新しいサービス アカウントを作成します。
gcloud iam service-accounts create pubsub-cloud-run-invoker --display-name "PubSub Cloud Run Invoker"

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

サービス アカウントの作成
  1. 新しいサービス アカウントに、メールサービスを呼び出す権限を付与します。
gcloud run services add-iam-policy-binding email-service --member=serviceAccount:pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com --role=roles/run.invoker --region {{{project_0.default_region | "REGION"}}} --platform managed

次に、「new-lab-report」メッセージがパブリッシュされたときにメールサービスを呼び出すよう Pub/Sub を設定します。

  1. 簡単に利用できるように、プロジェクト番号を環境変数に設定します。
PROJECT_NUMBER=$(gcloud projects list --filter="qwiklabs-gcp" --format='value(PROJECT_NUMBER)')

次に、プロジェクトで Pub/Sub 認証トークンを作成できるようにします。

  1. 次のコマンドを実行します。
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com --role=roles/iam.serviceAccountTokenCreator
  1. 別の環境変数にメールサービスの URL を設定します。
EMAIL_SERVICE_URL=$(gcloud run services describe email-service --platform managed --region {{{project_0.default_region | "REGION"}}} --format="value(status.address.url)")
  1. EMAIL_SERVICE_URL が正しく取得されたことを確認します。
echo $EMAIL_SERVICE_URL
  1. メールサービス用に Pub/Sub サブスクリプションを作成します。
gcloud pubsub subscriptions create email-service-sub --topic new-lab-report --push-endpoint=$EMAIL_SERVICE_URL --push-auth-service-account=pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com

これで、Cloud Pub/Sub メッセージに反応するようにサービスを設定できました。次のステップでは、コードを検証して、要件に合っているかを確認します。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

Pub/Sub サブスクリプションの作成

検査報告書サービスとメールサービスのテスト

  1. 先ほど作成したスクリプトを使用して、もう一度検査報告書を POST で送信します。
~/pet-theory/lab05/lab-service/post-reports.sh
  1. ログを開きます(ナビゲーション メニュー > [Cloud Run])。アカウントに 2 つの Cloud Run サービス、email-servicelab-report-service が表示されます。

  2. [email-service]、[ログ] の順にクリックします。
    このサービスが Pub/Sub によってトリガーされた結果が表示されます。目的のメッセージが表示されない場合は、スクロールバーを上下に動かしてログを更新してください。

お疲れさまでした。Cloud Pub/Sub トピックキューからメッセージが処理されるたびに、メールサービスからログに情報が書き込まれるようになりました。最後のタスクとして、SMS サービスを記述します。

タスク 4. SMS サービス

Ruby さんが新しい SMS サービスを設定するお手伝いをしましょう。

SMS サービスがハイライト表示されたアーキテクチャ図

SMS サービス用のコードの追加

  1. SMS サービス用のディレクトリを作成します。
cd ~/pet-theory/lab05/sms-service
  1. HTTPS リクエストを受信するのに必要なパッケージをインストールします。
npm install express npm install body-parser
  1. package.json ファイルを開きます。

  2. scripts セクションに以下のように "start": "node index.js", の行を追加して、ファイルを保存します。

... "scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, ... 注: コードは以下に示すとおりに最後のカンマまで含めて追加してください。

"start": "node index.js",

そうしないと、デプロイ中にエラーが発生します。
  1. index.js という名前の新しいファイルを作成して、以下のコードを追加します。
const express = require('express'); const app = express(); const bodyParser = require('body-parser'); app.use(bodyParser.json()); const port = process.env.PORT || 8080; app.listen(port, () => { console.log('Listening on port', port); }); app.post('/', async (req, res) => { const labReport = decodeBase64Json(req.body.message.data); try { console.log(`SMS Service: Report ${labReport.id} trying...`); sendSms(); console.log(`SMS Service: Report ${labReport.id} success :-)`); res.status(204).send(); } catch (ex) { console.log(`SMS Service: Report ${labReport.id} failure: ${ex}`); res.status(500).send(); } }) function decodeBase64Json(data) { return JSON.parse(Buffer.from(data, 'base64').toString()); } function sendSms() { console.log('Sending SMS'); }
  1. 次に、Dockerfile という名前のファイルを作成して、以下のコードを追加します。
FROM node:18 WORKDIR /usr/src/app COPY package.json package*.json ./ RUN npm install --only=production COPY . . CMD [ "npm", "start" ]

このファイルで、Cloud Run サービスをコンテナにパッケージ化する方法を定義します。コードを作成したら、次にサービスをデプロイします。

SMS サービスのデプロイ

  1. deploy.sh という名前のファイルを作成し、次のコードを追加します。
gcloud builds submit \ --tag gcr.io/$GOOGLE_CLOUD_PROJECT/sms-service gcloud run deploy sms-service \ --image gcr.io/$GOOGLE_CLOUD_PROJECT/sms-service \ --platform managed \ --region {{{project_0.default_region | "REGION"}}} \ --no-allow-unauthenticated \ --max-instances=1
  1. deploy.sh を実行可能にします。
chmod u+x deploy.sh
  1. SMS サービスをデプロイします。
./deploy.sh

デプロイが完了したら、以下のようなメッセージが表示されます。

Service [sms-service] revision [sms-service-00001] has been deployed and is serving traffic at https://sms-service-[hash].a.run.app

SMS サービスが正常にデプロイされましたが、Cloud Pub/Sub サービスにリンクされていません。次のセクションでは、この部分を修正します。

[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。

SMS サービスのデプロイ

Cloud Pub/Sub に SMS サービスをトリガーさせるための構成

メールサービスと同様に、Cloud Pub/Sub と SMS サービスとの間のリンクを構成して、メッセージを取得できるようにします。

Cloud Pub/Sub から SMS サービスへのフローがハイライト表示されたアーキテクチャ図

  1. Pub/Sub に SMS サービスをトリガーする権限を設定します。
gcloud run services add-iam-policy-binding sms-service --member=serviceAccount:pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com --role=roles/run.invoker --region {{{project_0.default_region | "REGION"}}} --platform managed

次に、「new-lab-report」メッセージがパブリッシュされたときに SMS サービスを呼び出すよう Pub/Sub を設定します。

  1. まず、環境変数に SMS サービスの URL アドレスを設定します。
SMS_SERVICE_URL=$(gcloud run services describe sms-service --platform managed --region {{{project_0.default_region | "REGION"}}} --format="value(status.address.url)")
  1. SMS_SERVICE_URL が正しく取得されたことを確認します。

    echo $SMS_SERVICE_URL
  2. 次に、Pub/Sub サブスクリプションを作成します。

gcloud pubsub subscriptions create sms-service-sub --topic new-lab-report --push-endpoint=$SMS_SERVICE_URL --push-auth-service-account=pubsub-cloud-run-invoker@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
  1. 再度テスト スクリプトを実行して、3 件の検査報告書を検査報告書サービスに POST で送信します。
~/pet-theory/lab05/lab-service/post-reports.sh
  1. ログを開きます(ナビゲーション メニュー > [Cloud Run])。アカウントに 3 つの Cloud Run サービス、email-service、lab-report-service、sms-service が表示されます。

  2. [sms-service]、[ログ] の順にクリックします。このサービスが Pub/Sub によってトリガーされた結果が表示されます。

これで、プロトタイプ システムが作成され、テストが正常に終わりました。ですが、Patrick さんは最初の検証プロセスで復元性をテストしていないことを心配しています。

タスク 5. システムの復元性のテスト

いずれかのサービスが停止したらどうなるでしょう。サービスの停止はよくあることで、Patrick さんも以前にこのような状況に遭遇したことがあります。

システムがこのような状況に対処できる方法を Ruby さんが調査するお手伝いをしましょう。彼女は、不正なバージョンのメールサービスをデプロイして、サービスが停止したときにどうなるかテストしたいと考えています。

  1. email-service ディレクトリに戻ります。
cd ~/pet-theory/lab05/email-service

エラーを発生させるために、正しくないテキストをメールサービス アプリケーションに追加します。

  1. 以下のように、index.js を編集して sendEmail() 関数に throw の行を追加します。これにより、メールサーバーが停止している場合と同様に例外がスローされます。
... function sendEmail() { throw 'Email server is down'; console.log('Sending email'); } ...

このコードを追加すると、サービスが呼び出されたときにクラッシュします。

  1. この不正なバージョンのメールサービスをデプロイします。
./deploy.sh
  1. メールサービスのデプロイが正常に完了したら、検査報告書サービスに再度データを POST で送信し、email-service のログステータスを詳しく調べます。
~/pet-theory/lab05/lab-service/post-reports.sh
  1. 不正なメールサービスのログを開きます(ナビゲーション メニュー > [Cloud Run])。

  2. アカウントに 3 つの Cloud Run サービスを確認したら、[email-service] をクリックします。

メールサービスが呼び出されていますが、クラッシュを繰り返しています。ログを少し遡ると「Email server is down」とあります。これが根本的な原因です。サービスがステータス コード 500 を返していることと、Pub/Sub がサービスを繰り返し呼び出していることもわかります。

SMS サービスのログを見ると、正常に動作していることがわかります。

メールサービスのエラーを修正して、アプリケーションを復元します。

  1. index.js ファイルを開き、先ほど入力した throw の行を削除してファイルを保存します。

index.jssendEmail 関数は以下のようになります。

function sendEmail() { console.log('Sending email'); }
  1. 修正したバージョンのメールサービスをデプロイします。
./deploy.sh
  1. デプロイが完了したら、右上隅の更新アイコンをクリックします。

報告書 12、34、56 のメールが正常に送信され、メールサービスがステータス コード 204 を返し、Pub/Sub がサービス呼び出しの再試行を停止したことがわかります。Pub/Sub は正常にサービスを呼び出せるまで再試行を続けていたので、データは失われていません。これで堅牢なシステムの基盤ができあがりました。

要点

  1. 複数のサービスが直接お互いを呼び出すのではなく、Pub/Sub を介して相互に非同期通信を行うことで、システムの復元性を高めることができます。
  2. 検査報告書サービスは、Pub/Sub を使用することで他のサービスとは独立してトリガーされます。たとえば、顧客が別のメッセージ サービスを通して検査結果を受け取りたい場合でも、検査報告書サービスを更新することなくその機能を追加できます。
  3. 再試行の処理は Cloud Pub/Sub が担当するので、サービスによる再試行は不要です。サービスは、成功または失敗を示すステータス コードを返すだけです。
  4. サービスが停止した場合でも Pub/Sub が再試行を続けるので、サービスがオンラインに戻ったときにシステムを自動的に回復できます。

お疲れさまでした

あなたのサポートにより、Ruby さんは復元性に優れたプロトタイプ システムを構築することに成功しました。サービスを通して、すべての飼い主にメールと SMS メッセージを自動的に送信できます。個別のサービスが一時的に停止した場合でも、システムに再試行のメカニズムが組み込まれているので、データが失われることはありません。Ruby さんは素晴らしい成果を上げたことで、称賛されました。

Lily

Lily さん(Pet Theory の創業者)

Ruby さん、お世話になっております。

リーダーシップを発揮して一生懸命作業に取り組んでいただき、感謝の言葉もありません。

非常に短期間で、当院の重要なシステムを一新することができました。

金曜日にささやかな祝賀会を開きますので、主賓としてお招きできればと思います。

Lily

Melody さん(マネージング ディレクター)Melody

Ruby さん、お疲れ様です。

Pet Theory 様から、すばらしい仕事をしたとお褒めの言葉をいただきました。あなたのおかげで、チームの評価が非常に高まりました。

この業務を見事に成し遂げてくれたので、次のプロジェクトではより責任のある役割を任せたいと思います。相談させてください。

Melody

マネージング ディレクター

Computer Consulting Inc.

クエストを完了する

このセルフペース ラボは、「Google Cloud Run Serverless Workshop」クエストの一部です。クエストとは学習パスを構成する一連のラボのことで、完了すると成果が認められて上のようなバッジが贈られます。バッジは公開して、オンライン レジュメやソーシャル メディア アカウントにリンクできます。このラボの修了後、こちらのクエストに登録すれば、すぐにクレジットを受け取ることができます。受講可能なその他のクエストもご確認ください

次のラボを受講する

シリーズの次のラボ「Go と Cloud Run を使用した REST API の開発」に進んでクエストを続けてください。

次のステップと詳細情報

Medium の記事: Cloud Run as an internal async worker

Google Cloud トレーニングと認定資格

Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。必要な技術スキルとベスト プラクティスについて取り扱うクラスでは、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。

マニュアルの最終更新日: 2023 年 9 月 20 日

ラボの最終テスト日: 2023 年 9 月 20 日

Copyright 2024 Google LLC All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。