GSP650
概要
「サーバーレス Cloud Run 開発」コースのラボでは、架空のビジネス シナリオを読み進めながら、登場人物のサーバーレス移行計画を進めていきます。
12 年前、リリーさんは動物病院チェーン「Pet Theory」を開業しました。その後、クリニックの数は年々増え、自動化の必要性も高まっています。Pet Theory では、検査会社から戻ってきた医療検査の結果の処理に時間がかかり、ミスも起こりやすいため、リリーさんはこの状況を改善したいと考えています。
現在、Pet Theory の IT 管理者であるパトリックさんは、検査結果を手作業で処理しています。検査結果が戻ってくるたびに、検査を受けたペットの飼い主にまずメールで結果を知らせ、その後、スマートフォンでテキスト メッセージを入力して、同じ内容を再度送っています。
パトリックさんはソフトウェア コンサルタントのルビーさんと協力し、よりスケーラブルなシステムを設計しようとしています。継続的なメンテナンスにそれほど手間がかからないソリューションを構築したいと考え、2 人はサーバーレス テクノロジーを採用することにしました。
目標
このラボでは、次の方法について学びます。
- Pub/Sub トピックとサブスクリプションを作成する。
- メッセージをパブリッシュおよび受信する Cloud Run サービスを作成する。
- Cloud Run サービスをトリガーする Pub/Sub サブスクリプションを作成する。
- システムの復元性をテストする。
前提条件
Cloud コンソールとシェル環境に関する基本的な知識があることを前提としています。このラボは一連のラボの一部です。必須ではありませんが、事前に次のラボを受講しておくと役立ちます。
設定と要件
注: このラボでは、Username 1 を使用して Google Cloud コンソールにログインしてください。それ以外のユーザー名でログインすると、ラボの実施中にエラーが発生します。
[ラボを開始] ボタンをクリックする前に
こちらの説明をお読みください。ラボには時間制限があり、一時停止することはできません。タイマーは、Google Cloud のリソースを利用できる時間を示しており、[ラボを開始] をクリックするとスタートします。
このハンズオンラボでは、シミュレーションやデモ環境ではなく実際のクラウド環境を使って、ラボのアクティビティを行います。そのため、ラボの受講中に Google Cloud にログインおよびアクセスするための、新しい一時的な認証情報が提供されます。
このラボを完了するためには、下記が必要です。
- 標準的なインターネット ブラウザ(Chrome を推奨)
注: このラボの実行には、シークレット モード(推奨)またはシークレット ブラウジング ウィンドウを使用してください。これにより、個人アカウントと受講者アカウント間の競合を防ぎ、個人アカウントに追加料金が発生しないようにすることができます。
- ラボを完了するための時間(開始後は一時停止できません)
注: このラボでは、受講者アカウントのみを使用してください。別の Google Cloud アカウントを使用すると、そのアカウントに料金が発生する可能性があります。
ラボを開始して Google Cloud コンソールにログインする方法
-
[ラボを開始] ボタンをクリックします。ラボの料金をお支払いいただく必要がある場合は、表示されるダイアログでお支払い方法を選択してください。
右側の [ラボの設定とアクセス] パネルには、以下が表示されます。
- [Google Cloud コンソールを開く] ボタン
- このラボで使用する一時的な認証情報(ユーザー名とパスワード)
- このラボを行うために必要なその他の情報(ある場合)
ラボのタイマーはページの上部に表示され、残り時間が示されます。
-
[Google Cloud コンソールを開く] をクリックします(Chrome ブラウザを使用している場合は、右クリックして [シークレット ウィンドウで開く] を選択します)。
ラボでリソースがスピンアップし、別のタブで [ログイン] ページが表示されます。
ヒント: タブをそれぞれ別のウィンドウで開き、並べて表示しておきましょう。
注: [アカウントの選択] ダイアログが表示された場合は、[別のアカウントを使用] をクリックします。
-
必要に応じて、下のユーザー名をコピーして、[ログイン] ダイアログに貼り付けます。
{{{user_0.username | "Username"}}}
[ラボの設定とアクセス] パネルでもユーザー名を確認できます。
-
[次へ] をクリックします。
-
以下のパスワードをコピーして、[ようこそ] ダイアログに貼り付けます。
{{{user_0.password | "Password"}}}
[ラボの設定とアクセス] パネルでもパスワードを確認できます。
-
[次へ] をクリックします。
重要: ラボで指定された認証情報を使用する必要があります。ご自身の Google Cloud アカウントの認証情報は使用しないでください。
注: このラボでご自身の Google Cloud アカウントを使用すると、追加料金が発生する場合があります。
-
その後のページはクリックして先に進みます。
- 利用規約に同意します。
- 一時的なアカウントなので、復元オプションや 2 要素認証プロセスは設定しないでください。
- 無料トライアルには登録しないでください。
しばらくすると、このタブで Google Cloud コンソールが開きます。
注: Google Cloud のプロダクトやサービスにアクセスするには、ナビゲーション メニューをクリックするか、[検索] フィールドにサービス名またはプロダクト名を入力します。
Cloud Shell をアクティブにする
Cloud Shell は、開発ツールと一緒に読み込まれる仮想マシンです。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働します。Cloud Shell を使用すると、コマンドラインで Google Cloud リソースにアクセスできます。
-
Google Cloud コンソールの上部にある「Cloud Shell をアクティブにする」アイコン
をクリックします。
-
ウィンドウで次の操作を行います。
- Cloud Shell 情報ウィンドウで操作を進めます。
- Cloud Shell が認証情報を使用して Google Cloud API を呼び出すことを承認します。
接続した時点で認証が完了しており、プロジェクトに各自の Project_ID、 が設定されます。出力には、このセッションの PROJECT_ID を宣言する次の行が含まれています。
Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}
gcloud は Google Cloud のコマンドライン ツールです。このツールは、Cloud Shell にプリインストールされており、タブ補完がサポートされています。
- (省略可)次のコマンドを使用すると、有効なアカウント名を一覧表示できます。
gcloud auth list
- [承認] をクリックします。
出力:
ACTIVE: *
ACCOUNT: {{{user_0.username | "ACCOUNT"}}}
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (省略可)次のコマンドを使用すると、プロジェクト ID を一覧表示できます。
gcloud config list project
出力:
[core]
project = {{{project_0.project_id | "PROJECT_ID"}}}
注: Google Cloud における gcloud ドキュメントの全文については、gcloud CLI の概要ガイドをご覧ください。
リージョンとゾーンを設定する
一部の Compute Engine リソースは、リージョン内やゾーン内に存在します。リージョンとは、リソースを実行できる特定の地理的なロケーションです。1 つのリージョンには 1 つ以上のゾーンがあります。
Cloud Shell で次の 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 では、飼い主に検査結果を伝えるプロセスを自動化したいと考えています。予約件数の増加に対応するのが難しくなってきたため、リリーさんはルビーさんに協力を依頼することにしました。
|

リリーさん(Pet Theory 創業者)
|
ルビーさん、お世話になっております。
先日は保険ポータルの件に対応していただき、ありがとうございました。
医療検査の結果についても何か改善できないでしょうか。飼い主さんにもっと効率よく結果を送る方法が必要なのです。
リリー
|
|

ルビーさん(ソフトウェア コンサルタント)
|
リリーさん、ご連絡ありがとうございます。
わかりました。現状を改善できそうなアイデアがいくつかありますので、検討したいと思います。
ルビー
|
タスク 1. アーキテクチャ
Pet Theory では、医療検査を外部の検査会社に委託しています。検査会社で医療検査が完了すると、結果が Pet Theory に返送されます。
検査会社は、HTTP(S) POST を使用して、Pet Theory のウェブ エンドポイントに検査結果を送信します。次の図は、全般的なアーキテクチャの概要を示しています。

ルビーさんは、現在のプロセス全体を確認したうえで、次の処理を行うシステムを設計できると考えました。
- HTTP POST リクエストを受信し、検査会社に受信確認を返す。
- 検査結果を飼い主にメールで送信する。
- 同じ検査結果を飼い主にテキスト メッセージ(SMS)でも送信する。
ルビーさんの設計では、上記の各処理を個別のサービスとして構成します。そのため、次の要素が必要になります。
- 検査結果のリクエストを受信し、応答を返すサービス
- 検査結果を飼い主にメールで送信するサービス
- 飼い主にテキスト メッセージ(SMS)を送信するサービス
- サービス間通信に使用する Pub/Sub
- アプリケーション アーキテクチャに使用するサーバーレス インフラストラクチャ
ルビーさんは、用途を 1 つに絞った関数を使用することで、記述しやすく、バグの少ないコードを開発しようと考えています。
|

ルビーさん(ソフトウェア コンサルタント)
|
パトリックさん、お世話になっております。
リリーさんから、検査結果の処理を支援するプロトタイプを作成したいという相談がありました。
まず、new-lab-report という名前の Pub/Sub トピックを設定していただけないでしょうか。
ルビー
|
|

パトリックさん(IT 管理者)
|
ルビーさん、ご連絡ありがとうございます。
面白そうなプロジェクトですね。どちらも Google Cloud ですぐに設定できる作業ですので、今朝のうちに終わらせようと思います。
パトリック
|
Pub/Sub トピックの作成
パトリックさんが new-lab-report という Pub/Sub トピックを作成するのをお手伝いしましょう。

サービスが Pub/Sub メッセージをパブリッシュするには、そのメッセージの送信先となるトピックを指定する必要があります。ここで作成するトピックに対して、Lab Report Service は受け取った検査結果ごとにメッセージをパブリッシュします。
まず、このタスクで使用するトピックを作成します。
- 次のコマンドを実行して、Pub/Sub トピックを作成します。
gcloud pubsub topics create new-lab-report
トピック「new-lab-report」に送られたメッセージを受信するよう設定されているサービスはすべて、Lab Report Service がパブリッシュしたメッセージを受信できます。上記の図では、そうしたメッセージを受信するサービスとして、Email Service と SMS Service の 2 つが示されています。
- 次に、クラウドでコードを実行する Cloud Run を有効にします。
gcloud services enable run.googleapis.com
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
Pub/Sub トピックの作成
Pub/Sub トピックの準備ができたことをルビーさんに伝えましょう。
|

パトリックさん(IT 管理者)
|
ルビーさん、お世話になっております。
作業が終わりました。
お手数でなければ、このプロトタイプをどうやって作っていくのか、私も見てみたいです。一緒に作業してもよいでしょうか。
パトリック
|
|

ルビーさん(ソフトウェア コンサルタント)
|
パトリックさん、ご連絡ありがとうございます。
迅速に対応していただき助かりました。時間を作りますので、一緒に作成作業を進めましょう。
ルビー
|
タスク 2. Lab Report Service のビルド
ルビーさんが新しい Lab Report Service を設定するお手伝いをしましょう。

このサービスはプロトタイプ用であるため、行う処理は次の 2 つだけです。
- 検査結果データを含む HTTPS POST を受信する
- Pub/Sub にメッセージをパブリッシュする
Lab Report Service 用のコードの追加
- Cloud Shell に戻り、このラボに必要なリポジトリのクローンを作成します。
git clone https://github.com/rosera/pet-theory.git
-
lab-service ディレクトリに移動します。
cd pet-theory/lab05/lab-service
- 受信した HTTPS リクエストを処理し、Pub/Sub にパブリッシュするために必要な次のパッケージをインストールします。
npm install express
npm install body-parser
npm install @google-cloud/pubsub
これらのコマンドにより、package.json ファイルが更新され、このサービスに必要な依存関係が示されます。
次に、Cloud Run がコードの起動方法を認識できるよう、package.json ファイルを編集します。
-
package.json ファイルを開きます。
-
package.json ファイルの「scripts」セクションの 7 行目に、次のようにコード行 "start": "node index.js", を追加し、ファイルを保存します。
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
注: 末尾のカンマを含め、次のコードを必ず示されているとおりに追加してください。
"start": "node index.js",
そうしないと、デプロイ中にエラーが発生します。
-
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);
具体的には、この 2 行で次の処理を行います。
- POST リクエストから検査結果を抽出する。
- 新たに POST された検査結果を含む Pub/Sub メッセージをパブリッシュする。
- 次に、
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 のデプロイ
-
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
- Cloud Shell で次のコマンドを実行し、このファイルを実行可能にします。
chmod u+x deploy.sh
- いよいよ Lab Report Service をデプロイします。デプロイ スクリプトを実行します。
./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
これで、Lab Report Service がデプロイされ、HTTP 経由で医療検査の結果を受信できるようになりました。次に、この新しいサービスが正しく稼働しているかをテストします。
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
Lab Report Service のデプロイ: ビルド
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
Lab Report Service のデプロイ: リビジョンの作成
Lab Report Service のテスト
Lab Report Service を検証するために、検査会社から送信される 3 件の HTTPS POST をシミュレートします。各 POST には、1 件の検査結果が含まれています。テストで使用する検査結果データには ID のみを含めます。
- まず、作業しやすいように Lab Report Service の 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)")
- LAB_REPORT_SERVICE_URL が取得されていることを確認します。
echo $LAB_REPORT_SERVICE_URL
-
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 コマンドを使用して、Lab Report Service の URL に 3 つの異なる ID を POST します。各コマンドはバックグラウンドで個別に実行されます。
-
post-reports.sh スクリプトを実行可能にします。
chmod u+x post-reports.sh
- 上記のスクリプトを使用して 3 件の検査結果を POST し、Lab Report Service のエンドポイントをテストします。
./post-reports.sh
このスクリプトにより、3 件の検査結果が Lab Report Service に POST されました。ログで結果を確認します。
-
Google Cloud コンソールで、ナビゲーション メニュー(
)> [Cloud Run] をクリックします。
-
新しくデプロイした lab-report-service が [サービス] リストに表示されたら、これをクリックします。
-
次のページに、lab-report-service の詳細が表示されます。[ログ] タブをクリックします。
[ログ] ページには、先ほどスクリプトを使用して POST した 3 件の検査結果の処理結果が表示されます。以下のように、HTTP ステータス コード 204(No Content)が返されていれば成功です。エントリが表示されない場合は、右側のスクロールバーを上下に動かしてみてください。これにより、ログが再読み込みされます。
次のタスクでは、SMS Service と Email Service を記述します。これらのサービスは、Lab Report Service が「new-lab-report」トピックに Pub/Sub メッセージをパブリッシュするとトリガーされます。
タスク 3. Email Service
ルビーさんが新しい Email Service を設定するのをお手伝いしましょう。

Email Service 用のコードの追加
- Email Service のディレクトリに移動します。
cd ~/pet-theory/lab05/email-service
- 受信した HTTPS リクエストをコードで処理できるように、次のパッケージをインストールします。
npm install express
npm install body-parser
上記のコマンドにより、アプリケーションとその依存関係を記述する package.json ファイルが更新されます。Cloud Run がコードの実行方法を認識できるように、start スクリプトを追加します。
-
package.json ファイルを開きます。
-
「scripts」セクションに、次のように "start": "node index.js", の行を追加し、ファイルを保存します。
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
注: 末尾のカンマを含め、次のコードを必ず示されているとおりに追加してください。
"start": "node index.js",
そうしないと、デプロイ中にエラーが発生します。
-
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 は後で、そのメッセージをサービスに再度 POST する。
サービス間の通信が正常に動作することを確認できたら、sendEmail() 関数にコードを追加し、実際にメールを送信できるようにします。
- 次に、
Dockerfile という名前のファイルを作成し、次のコードを追加します。
FROM node:18
WORKDIR /usr/src/app
COPY package.json package*.json ./
RUN npm install --only=production
COPY . .
CMD [ "npm", "start" ]
このファイルでは、Cloud Run サービスをコンテナとしてパッケージ化する方法を定義します。
Email Service のデプロイ
-
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
-
deploy.sh を実行可能にします。
chmod u+x deploy.sh
- Email Service をデプロイします。
./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 メッセージを利用できるようになったときに Email Service がトリガーされるよう設定します。
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
Email Service のデプロイ: ビルド
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
Email Service のデプロイ: リビジョンの作成
Pub/Sub で Email Service をトリガーするための構成
「new-lab-report」トピックを使用して新しい Pub/Sub メッセージがパブリッシュされるたびに、Email Service がトリガーされるようにします。そのためには、Pub/Sub がこのサービスを自動的に呼び出せるように、サービス アカウントを構成する必要があります。

- Pub/Sub メッセージに応答するサービスをトリガーするための新しいサービス アカウントを作成します。
gcloud iam service-accounts create pubsub-cloud-run-invoker --display-name "PubSub Cloud Run Invoker"
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
サービス アカウントの作成
- 新しいサービス アカウントに、Email Service を呼び出す権限を付与します。
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」メッセージがパブリッシュされたときに Email Service を呼び出すよう Pub/Sub を設定します。
- 簡単に参照できるように、プロジェクト番号を環境変数に設定します。
PROJECT_NUMBER=$(gcloud projects list --filter="qwiklabs-gcp" --format='value(PROJECT_NUMBER)')
次に、プロジェクトで Pub/Sub 認証トークンを作成できるようにします。
- 次のコマンドを実行します。
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT --member=serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com --role=roles/iam.serviceAccountTokenCreator
- Email Service の URL を別の環境変数に設定します。
EMAIL_SERVICE_URL=$(gcloud run services describe email-service --platform managed --region {{{project_0.default_region | "REGION"}}} --format="value(status.address.url)")
- EMAIL_SERVICE_URL が取得されていることを確認します。
echo $EMAIL_SERVICE_URL
- Email Service 用の 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 サブスクリプションの作成
Lab Report Service と Email Service のテスト
- 先ほど作成したスクリプトを使用して、検査結果をもう一度 POST します。
~/pet-theory/lab05/lab-service/post-reports.sh
-
次に、ログを開きます(ナビゲーション メニュー > [Cloud Run])。アカウントには、email-service と lab-report-service という 2 つの Cloud Run サービスが表示されます。
-
[email-service] をクリックし、続いて [ログ] をクリックします。
このサービスが Pub/Sub によってトリガーされたことを示す結果が表示されます。想定したメッセージが表示されない場合は、スクロールバーを上下に動かしてログを更新してみてください。
お疲れさまでした。これで、Cloud Pub/Sub トピック キューからメッセージが処理されるたびに、Email Service がログに情報を書き込めるようになりました。最後のタスクでは、SMS Service を記述します。
タスク 4. SMS Service
ルビーさんが新しい SMS Service を設定するのをお手伝いしましょう。

SMS Service 用のコードの追加
- SMS Service のディレクトリに移動します。
cd ~/pet-theory/lab05/sms-service
- 受信した HTTPS リクエストを処理するために必要なパッケージをインストールします。
npm install express
npm install body-parser
-
package.json ファイルを開きます。
-
「scripts」セクションに、次のように "start": "node index.js", の行を追加し、ファイルを保存します。
...
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
...
注: 末尾のカンマを含め、次のコードを必ず示されているとおりに追加してください。
"start": "node index.js",
そうしないと、デプロイ中にエラーが発生します。
-
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');
}
- 次に、
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 Service のデプロイ
-
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
-
deploy.sh を実行可能にします。
chmod u+x deploy.sh
- SMS Service をデプロイします。
./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 Service は正常にデプロイされましたが、まだ Cloud Pub/Sub にはリンクされていません。次のセクションで、このリンクを構成します。
[進行状況を確認] をクリックして、目標に沿って進んでいることを確認します。
SMS Service のデプロイ
Cloud Pub/Sub で SMS Service をトリガーするための構成
Email Service と同様に、Cloud Pub/Sub と SMS Service の間のリンクを構成し、メッセージを受信できるようにする必要があります。

- Pub/Sub が SMS Service をトリガーできるように権限を設定します。
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 Service を呼び出すよう Pub/Sub を設定します。
- まず、SMS Service の URL を環境変数に設定します。
SMS_SERVICE_URL=$(gcloud run services describe sms-service --platform managed --region {{{project_0.default_region | "REGION"}}} --format="value(status.address.url)")
-
SMS_SERVICE_URL が取得されていることを確認します。
echo $SMS_SERVICE_URL
-
次に、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
- テスト スクリプトをもう一度実行し、3 件の検査結果を Lab Report Service に POST します。
~/pet-theory/lab05/lab-service/post-reports.sh
-
次に、ログを開きます(ナビゲーション メニュー > [Cloud Run])。アカウントには、email-service、lab-report-service、sms-service という 3 つの Cloud Run サービスが表示されます。
-
[sms-service] をクリックし、続いて [ログ] をクリックします。このサービスが Pub/Sub によってトリガーされたことを示す結果が表示されます。
これで、プロトタイプ システムが作成され、正常にテストされました。ですが、パトリックさんは最初の検証段階で復元性がまだテストされていないことを心配しています。
タスク 5. システムの復元性のテスト
いずれかのサービスが停止した場合、どうなるでしょうか。このような状況は珍しくなく、パトリックさんも以前に経験したことがあります。
システムによるこのような状況への対処方法を調査するルビーさんのお手伝いをしましょう。ルビーさんは、不具合を含むバージョンの Email Service をデプロイし、サービスで障害が発生した場合にどうなるかをテストしたいと考えています。
-
email-service ディレクトリに戻ります。
cd ~/pet-theory/lab05/email-service
エラーが発生するように、Email Service アプリケーションに無効なテキストを追加します。
- 以下のように、
index.js を編集して sendEmail() 関数に throw の行を追加します。これにより、メールサーバーがダウンしているかのように例外がスローされます。
...
function sendEmail() {
throw 'Email server is down';
console.log('Sending email');
}
...
このコードを追加すると、サービスが呼び出されたときにクラッシュします。
- この不具合を含むバージョンの Email Service をデプロイします。
./deploy.sh
- Email Service のデプロイが正常に完了したら、Lab Report Service にもう一度データを POST し、email-service のログステータスを詳しく確認します。
~/pet-theory/lab05/lab-service/post-reports.sh
-
Email Service のログを開き、不具合を含む Email Service のログを確認します。ナビゲーション メニュー > [Cloud Run] の順にクリックします。
-
アカウントに 3 つの Cloud Run サービスが表示されたら、[email-service] をクリックします。
Email Service は呼び出されていますが、クラッシュを繰り返しています。ログを少し遡ると、根本原因である「Email server is down」が見つかります。また、サービスがステータス コード 500 を返しており、Pub/Sub がサービスの呼び出しを繰り返し試行していることも確認できます。
SMS Service のログを見ると、SMS Service は正常に動作していることがわかります。
次に、Email Service のエラーを修正して、アプリケーションを復元します。
-
index.js ファイルを開き、先ほど追加した throw の行を削除して、ファイルを保存します。
index.js の sendEmail 関数は、次のようになります。
function sendEmail() {
console.log('Sending email');
}
- 修正したバージョンの Email Service をデプロイします。
./deploy.sh
- デプロイが完了したら、右上にある更新アイコンをクリックします。
検査結果 12、34、56 のメールが最終的に送信され、Email Service がステータス コード 204 を返し、Pub/Sub によるサービスの呼び出しが停止したことを確認できます。Pub/Sub は処理が成功するまで再試行を続けていたため、データは失われていません。これで堅牢なシステムの基盤ができあがりました。
要点
- サービスどうしが直接呼び出し合うのではなく、Pub/Sub を介して非同期に通信することで、システムの復元性を高めることができます。
- Pub/Sub を使用することで、Lab Report Service のトリガーは他のサービスから独立します。たとえば、飼い主が別のメッセージング サービスでも検査結果の受け取りを希望した場合、Lab Report Service を更新せずにその機能を追加できます。
- 再試行は Cloud Pub/Sub が処理するため、各サービスで再試行を行う必要はありません。サービスは、成功または失敗を示すステータス コードを返すだけで済みます。
- サービスが停止した場合でも、Pub/Sub による再試行により、サービスがオンラインに戻った時点でシステムは自動的に復旧できます。
お疲れさまでした
ルビーさんは、あなたの支援を受けて、復元性に優れたプロトタイプ システムを構築できました。このサービスは、すべての飼い主にメールと SMS メッセージを自動的に送信できます。個別のサービスが一時的に停止した場合でも、システムには再試行メカニズムが組み込まれているため、データが失われることはありません。ルビーさんのもとに、その成果を称えるうれしいメッセージが届きました。
|

リリーさん(Pet Theory 創業者)
|
ルビーさん、お世話になっております。
プロジェクトをリードして懸命に取り組んでいただき、感謝の言葉もありません。
当院の重要なシステムをあっという間に一新することができました。
金曜日にささやかな慰労会を開きますので、ぜひ主賓としてご参加ください。
リリー
|
|
メロディーさん(マネージング ディレクター)
|
ルビーさん、お疲れ様です。
Pet Theory 様から、あなたのすばらしい仕事についてお褒めの言葉をいただきました。おかげで、チームの評価が大きく高まりました。
この業務が完了したところで、次のプロジェクトではもっと責任のある役割を任せたいと考えています。
メロディー
マネージング ディレクター
Computer Consulting Inc.
|
次のステップと詳細情報
Google Cloud トレーニングと認定資格
Google Cloud トレーニングと認定資格を通して、Google Cloud 技術を最大限に活用できるようになります。必要な技術スキルとベスト プラクティスについて取り扱うクラスでは、学習を継続的に進めることができます。トレーニングは基礎レベルから上級レベルまであり、オンデマンド、ライブ、バーチャル参加など、多忙なスケジュールにも対応できるオプションが用意されています。認定資格を取得することで、Google Cloud テクノロジーに関するスキルと知識を証明できます。
マニュアルの最終更新日: 2024 年 7 月 23 日
ラボの最終テスト日: 2024 年 7 月 23 日
Copyright 2026 Google LLC. All rights reserved. Google および Google のロゴは Google LLC の商標です。その他すべての企業名および商品名はそれぞれ各社の商標または登録商標です。