GSP650

概览
对于无服务器 Cloud Run 开发课程中的实验,您需要通读一个虚构的业务场景,并协助其中的人物完成无服务器迁移计划。
12 年前,Lily 创办了 Pet Theory 连锁宠物医院。多年来,宠物医院的数量不断增加,对自动化的需求也越来越高。在处理实验机构发回的医疗检验结果时,Pet Theory 采用的方式不仅速度太慢,而且容易出错,因此 Lily 想要改善这种情况。
目前,Pet Theory 的 IT 管理员 Patrick 采用手动方式处理检验结果。每当实验机构发回检验结果时,他都会撰写一封电子邮件并将其发送给检验了宠物的客户,然后在手机上输入短信,将结果以文本形式发送给客户。
Patrick 正在与软件顾问 Ruby 携手合作,设计一种扩缩能力更强的系统。他们希望构建一种不需要大量持续维护的解决方案。Patrick 和 Ruby 决定采用无服务器技术。
目标
在本实验中,您将学习如何完成以下操作:
- 创建 Pub/Sub 主题和订阅
- 创建一项 Cloud Run 服务,用于接收 HTTP 请求并将消息发布到 Cloud Pub/Sub
- 创建一项 Cloud Run 服务,用于接收来自 Cloud Pub/Sub 的消息
- 创建 Pub/Sub 订阅,用于触发 Cloud Run 服务
- 测试系统的弹性
前提条件
本实验假设您熟悉 Cloud 控制台和 shell 环境。本实验是一系列实验中的一个。完成之前的实验会有所帮助,但这不是硬性要求:
设置和要求
注意:在本实验中,请使用 Username 1 登录 Google Cloud 控制台。否则,您将在实验过程中遇到错误。
点击“开始实验”按钮前的注意事项
请阅读以下说明。实验是计时的,并且您无法暂停实验。计时器在您点击开始实验后即开始计时,显示 Google Cloud 资源可供您使用多长时间。
此实操实验可让您在真实的云环境中开展实验活动,免受模拟或演示环境的局限。我们会为您提供新的临时凭据,让您可以在实验规定的时间内用来登录和访问 Google Cloud。
为完成此实验,您需要:
- 能够使用标准的互联网浏览器(建议使用 Chrome 浏览器)。
注意:请使用无痕模式或无痕浏览器窗口运行此实验。这可以避免您的个人账号与学生账号之间发生冲突,这种冲突可能导致您的个人账号产生额外费用。
注意:如果您已有自己的个人 Google Cloud 账号或项目,请不要在此实验中使用,以避免您的账号产生额外的费用。
如何开始实验并登录 Google Cloud 控制台
-
点击开始实验按钮。如果该实验需要付费,系统会打开一个弹出式窗口供您选择付款方式。左侧是实验详细信息面板,其中包含以下各项:
-
打开 Google Cloud 控制台按钮
- 剩余时间
- 进行该实验时必须使用的临时凭据
- 帮助您逐步完成本实验所需的其他信息(如果需要)
-
点击打开 Google Cloud 控制台(如果您使用的是 Chrome 浏览器,请右键点击并选择在无痕式窗口中打开链接)。
该实验会启动资源并打开另一个标签页,显示登录页面。
提示:请将这些标签页安排在不同的窗口中,并将它们并排显示。
注意:如果您看见选择账号对话框,请点击使用其他账号。
-
如有必要,请复制下方的用户名,然后将其粘贴到登录对话框中。
{{{user_0.username | "<用户名>"}}}
您也可以在实验详细信息面板中找到用户名。
-
点击下一步。
-
复制下面的密码,然后将其粘贴到欢迎对话框中。
{{{user_0.password | "<密码>"}}}
您也可以在实验详细信息面板中找到密码。
-
点击下一步。
重要提示:您必须使用实验提供的凭据。请勿使用您的 Google Cloud 账号凭据。
注意:在本次实验中使用您自己的 Google Cloud 账号可能会产生额外费用。
-
继续在后续页面中点击以完成相应操作:
- 接受条款及条件。
- 由于该账号为临时账号,请勿添加账号恢复选项或双重验证。
- 请勿注册免费试用。
片刻之后,系统会在此标签页中打开 Google Cloud 控制台。
注意:如需查看列有 Google Cloud 产品和服务的菜单,请点击左上角的导航菜单。
激活 Cloud Shell
Cloud Shell 是一种装有开发者工具的虚拟机。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行。Cloud Shell 提供可用于访问您的 Google Cloud 资源的命令行工具。
- 点击 Google Cloud 控制台顶部的激活 Cloud Shell
。
如果您连接成功,即表示您已通过身份验证,且当前项目会被设为您的 PROJECT_ID 环境变量所指的项目。输出内容中有一行说明了此会话的 PROJECT_ID:
Your Cloud Platform project in this session is set to YOUR_PROJECT_ID
gcloud
是 Google Cloud 的命令行工具。它已预先安装在 Cloud Shell 上,且支持 Tab 自动补全功能。
- (可选)您可以通过此命令列出活跃账号名称:
gcloud auth list
-
点击授权。
-
现在,输出的内容应如下所示:
输出:
ACTIVE: *
ACCOUNT: student-01-xxxxxxxxxxxx@qwiklabs.net
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- (可选)您可以通过此命令列出项目 ID:
gcloud config list project
输出:
[core]
project = <project_ID>
输出示例:
[core]
project = qwiklabs-gcp-44776a13dea667a6
Note: For full documentation of gcloud
, in Google Cloud, refer to the gcloud CLI overview guide.
设置区域和可用区
某些 Compute Engine 资源位于区域和可用区内。区域是指某个地理位置,您可以在其中运行自己的资源。每个区域包含一个或多个可用区。
在 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,Pet Theory 创始人
|
Ruby,您好!
谢谢您帮我整理保险门户。
我想知道在医疗检验结果方面能不能做些什么?我们需要一种更高效的方式来将结果发送给客户。
Lily
|

Ruby,软件顾问
|
Lily,您好!
没问题,我看看能提供哪些帮助。我有一些想法,也许能改善这种情况。
Ruby
|
任务 1. 架构
Pet Theory 通过外部公司进行医疗检验。实验机构完成医疗检验后,便会将结果发回给 Pet Theory。
实验机构通过 HTTP(s) POST 将医疗实验结果发送到 Pet Theory 的 Web 端点。下图概述了总体架构。

在了解所遵循的常规流程后,Ruby 认为可以设计出一个系统,让 Pet Theory 能够执行以下操作:
- 接收 HTTP POST 请求,并确认已收到医疗实验结果。
- 通过电子邮件将检验结果发送给客户。
- 向客户发送有关检验结果的短信和电子邮件。
Ruby 的设计可将上述各项活动隔离开来,并且需要以下各项:
- 用于针对医疗结果执行请求和响应的服务
- 用于通过电子邮件将检验结果发送给客户的服务
- 用于向客户发送短信的服务
- 用于服务间通信的 Pub/Sub
- 用于应用架构的无服务器基础设施
通过使用一次性函数,Ruby 希望开发出更易于编写且包含更少 bug 的代码。

Ruby,软件顾问
|
Patrick,您好!
Lily 希望我构建一个原型来帮助处理医疗记录。
您能不能设置一个名为 new-lab-report 的 Pub/Sub 主题,以便我开始构建?
Ruby
|

Patrick,IT 管理员
|
Ruby,您好!
这个项目听起来很不错。我今天上午就能完成,这两项活动都可以在 Google Cloud 上快速设置完毕。
Patrick
|
创建 Pub/Sub 主题
帮助 Patrick 创建名为 new-lab-report
的 Pub/Sub 主题。

当服务发布 Pub/Sub 消息时,相应消息必须使用主题进行标记。实验报告通过要创建的服务进行使用,该服务会为找到的每份报告发布一条消息。
首先,您需要创建可用于此任务的主题。
- 运行以下命令,创建 Pub/Sub 主题:
gcloud pubsub topics create new-lab-report
凡是订阅“new-lab-report”主题的服务,都可以使用实验报告服务发布的消息。在上图中,您可以看到两种使用这类消息的服务,即电子邮件服务和短信服务。
- 然后启用 Cloud Run,在云端运行代码:
gcloud services enable run.googleapis.com
点击检查我的进度以验证是否完成了以下目标:
创建 Pub/Sub 主题
别忘了告知 Ruby 最新进展,让她知道 Pub/Sub 主题已准备就绪!

Patrick,IT 管理员
|
Ruby,您好!
大功告成。
如果您有时间,我想看看这个原型是如何构建的。我们能一起处理这个问题吗?
Patrick
|

Ruby,软件顾问
|
Patrick,您好!
太好了,感谢您如此快速地完成设置。我会安排好时间,然后我们就可以开始构建。
Ruby
|
任务 2. 构建实验报告服务
帮助 Ruby 设置新的实验报告服务。

这项服务可用于设计原型,因此仅用于执行以下两项操作:
- 接收包含报告数据的实验报告 HTTPS POST。
- 在 Pub/Sub 上发布消息。
为实验报告服务添加代码
- 返回到 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
文件,以指出此服务所需的依赖项。
现在,您要修改 package.json
文件,以便 Cloud Run 知道如何启动代码。
-
打开 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);
}
以下两行代码负责处理服务的主要工作:
const labReport = req.body;
await publishPubSubMessage(labReport);
具体来说,这几行代码的作用是:
- 从 POST 请求中提取实验报告。
- 发布 PubSub 消息,其中包含新发布的实验报告。
- 现在,创建一个名为
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
- 现在可以部署实验报告服务了!运行部署脚本:
./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 使用医疗实验结果。现在,您可以测试新服务是否已启动并正常运行。
点击检查我的进度以验证是否完成了以下目标:
部署实验报告服务:构建
点击检查我的进度以验证是否完成了以下目标:
部署实验报告服务:创建修订版本
测试实验报告服务
若要验证实验报告服务,请模拟实验机构发出的三个 HTTPS POST,每个 POST 包含一份实验报告。为了进行测试,创建的实验报告只包含一个 ID。
- 首先,将报告网址放入环境变量中,以便更轻松地处理报告。
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
命令,将三个不同的 ID 发布到实验服务网址。每个命令都将在后台单独运行。
- 使
post-reports.sh
脚本可执行:
chmod u+x post-reports.sh
- 现在,使用上述脚本将三份实验报告发布到实验报告服务端点,以对其进行测试:
./post-reports.sh
此脚本已将三份实验报告发布到实验报告服务。请检查日志以查看结果!
-
在 Cloud 控制台中,依次点击导航菜单 (
) > Cloud Run。
-
现在,您应该会在服务列表中看到新部署的 lab-report-service。点击该服务。
-
在随即打开的页面中,您会看到有关 lab-report-service 的详细信息。点击日志标签页。
在“日志”页面上,您会看到自己刚刚使用脚本发布的三份检验报告的结果。希望返回的是 HTTP 代码 204,这表示已成功处理请求,但没有任何响应内容,如下所示。如果您没有看到任何条目,请尝试使用右侧的滚动条上下滚动。这会重新加载日志。
下一项任务是编写短信和电子邮件服务。当实验报告服务使用“new-lab-report”主题发布 Pub/Sub 消息时,系统就会触发这些服务。
任务 3. 电子邮件服务
帮助 Ruby 设置新的电子邮件服务。

为电子邮件服务添加代码
- 移动到电子邮件服务目录:
cd ~/pet-theory/lab05/email-service
- 安装以下软件包,以便代码能够处理传入的 HTTP 请求:
npm install express
npm install body-parser
上述命令会更新 package.json
文件,该文件用于描述应用及其依赖项。Cloud Run 需要知道如何运行代码,因此请添加 start
指令,以便 Cloud Run 知道如何操作。
-
打开 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 将消息发布到服务时运行。这段代码的作用如下:
- 对 Pub/Sub 消息进行解码,然后尝试调用
sendEmail()
函数。
- 如果上述操作成功且没有抛出异常,服务将返回状态代码 204,以便 Pub/Sub 知道消息已被处理。
- 如果存在异常,服务将返回状态代码 500,以便让 Pub/Sub 知道消息未被处理,稍后应将消息重新发布到服务。
服务之间正常通信后,Ruby 会将代码添加到 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 服务打包到容器中。
部署电子邮件服务
- 创建一个名为
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
- 部署电子邮件服务:
./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 消息时,都应触发电子邮件服务。若要完成这项任务,请配置服务账号来自动处理此服务的相关请求。

- 创建新的服务账号,用于触发服务来响应 Pub/Sub 消息:
gcloud iam service-accounts create pubsub-cloud-run-invoker --display-name "PubSub Cloud Run Invoker"
点击检查我的进度以验证是否完成了以下目标:
创建服务账号
- 授予新服务账号调用电子邮件服务的权限:
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
接下来,指示 Pub/Sub 在“new-lab-report”消息发布时调用短信服务。
- 将项目编号放入环境变量中,以便轻松访问:
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=$(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
- 为电子邮件服务创建 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 订阅
同时测试实验报告服务和电子邮件服务
- 使用之前创建的脚本,再次将消息发布到实验报告:
~/pet-theory/lab05/lab-service/post-reports.sh
-
然后打开日志(导航菜单 > Cloud Run)。您将在账号中看到两项 Cloud Run 服务,即 email-service 和 lab-report-service。
-
依次点击 email-service 和日志。
您将看到 Pub/Sub 触发这项服务的结果。如果您没有看到预期的消息,可能需要使用滚动条上下滚动,以刷新日志。
太棒了!现在,每当 Cloud Pub/Sub 主题队列中有消息处理完毕时,电子邮件服务就能将相关信息写入日志!最后一项任务是编写短信服务。
任务 4. 短信服务
帮助 Ruby 设置新的短信服务。

为短信服务添加代码
- 为短信服务创建目录:
cd ~/pet-theory/lab05/sms-service
- 安装所需的软件包,以接收传入的 HTTP 请求:
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 服务打包到容器中。现在,代码已创建完毕,下一步是部署服务。
部署短信服务
- 创建一个名为
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
- 部署短信服务:
./deploy.sh
部署完成后,系统会显示类似于以下内容的消息:
Service [sms-service] revision [sms-service-00001] has been deployed and is serving traffic at https://sms-service-[hash].a.run.app
短信服务已成功部署,但未关联到 Cloud Pub/Sub 服务。您将在下一部分进行更正。
点击检查我的进度以验证是否完成了以下目标:
部署短信服务
配置 Cloud Pub/Sub 以触发短信服务
与电子邮件服务一样,需要配置 Cloud Pub/Sub 和短信服务之间的关联,以便使用消息。

- 设置相关权限,以允许 Pub/Sub 触发短信服务:
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
接下来,指示 Pub/Sub 在“new-lab-report”消息发布时调用短信服务。
- 第一步,将短信服务的网址放入环境变量中:
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
- 再次运行测试脚本,将三份实验报告发布到实验报告服务:
~/pet-theory/lab05/lab-service/post-reports.sh
-
然后打开日志(导航菜单 > Cloud Run)。您将在账号中看到三项 Cloud Run 服务,即 email-service、lab-report-service 和 sms-service。
-
依次点击 sms-service 和日志。您将看到 Pub/Sub 触发这项服务的结果。
原型系统已创建完毕并成功经过测试。然而,令 Patrick 担心的是,作为初始验证流程中的一环,系统弹性尚未经过测试。
任务 5. 测试系统的弹性
如果其中一项服务出现故障,会发生什么情况?Patrick 之前遇到过这种情况,因为这很常见。
帮助 Ruby 研究如何确保系统能够处理这种情况。她想要部署有问题的电子邮件服务版本,以测试服务出现故障时会发生什么情况。
- 返回
email-service
目录:
cd ~/pet-theory/lab05/email-service
在电子邮件服务应用中添加一些无效文本,使其出现错误。
- 修改
index.js
,并在 sendEmail()
函数中添加 throw
行,如下所示。这会抛出异常,就像电子邮件服务器出现故障一样:
...
function sendEmail() {
throw 'Email server is down';
console.log('Sending email');
}
...
添加这段代码后,服务会在调用时崩溃。
- 部署这个有问题的电子邮件服务版本:
./deploy.sh
- 电子邮件服务部署成功完成后,请再次将数据发布到实验报告,然后密切关注 email-service 日志状态:
~/pet-theory/lab05/lab-service/post-reports.sh
-
打开电子邮件服务日志,查看有问题的电子邮件服务的日志:导航菜单 > Cloud Run。
-
如果您在账号中看到三项 Cloud Run 服务,请点击 email-service。
系统正在调用电子邮件服务,但该服务总是崩溃。如果您在日志中向后滚动一下,便会找到根本原因:“电子邮件服务器出现故障”。您还可以看到,该服务返回了状态代码 500,并且 Pub/Sub 在不断重新尝试调用该服务。
如果您查看短信服务的日志,就会发现该服务已成功运行。
现在修复电子邮件服务中的错误,即可恢复应用!
- 打开
index.js
文件,移除您之前输入的 throw 行,然后保存文件。
您的 index.js
sendEmail
函数现在应类似于以下内容:
function sendEmail() {
console.log('Sending email');
}
- 部署修复后的电子邮件服务版本:
./deploy.sh
- 部署完成后,点击右上角的刷新图标。
您会看到以下内容:报告 12、34 和 56 的电子邮件最终是如何发送的,电子邮件服务返回了状态代码 204,以及 Pub/Sub 停止了调用服务。没有数据丢失;Pub/Sub 会不断重试,直至最终成功。这就是稳健系统的基础!
掌握要点
- 如果服务之间通过 Pub/Sub 进行异步通信,而不是直接相互调用,系统就会更具弹性。
- 由于使用 Pub/Sub,因此实验报告服务的触发独立于其他服务。例如,如果客户也想通过其他通讯服务接收实验结果,可以添加相应服务,而无需更新实验报告服务。
- Cloud Pub/Sub 已处理重试机制,服务无需进行处理。服务只需返回状态代码:成功或失败。
- 得益于 Pub/Sub 重试机制,如果服务出现故障,系统能够在服务恢复在线状态时自动自行“修复”。
恭喜!
在您的帮助下,Ruby 成功构建了弹性原型系统。该服务能够自动向每位客户发送电子邮件和短信。如果个别服务暂时出现故障,系统会实现重试机制,以免丢失任何数据。Ruby 获得了一些实至名归的称赞…

Lily,Pet Theory 创始人
|
Ruby,您好!
对于您的辛苦付出和领导,我们不胜感激。
在很短的时间内,我们的基本系统便得到了彻底改进。
我们周五会举办一场小型聚会来庆祝一下,如果您能成为我们的座上宾,那就太好了!
Lily
|
Melody,总经理
|
Ruby,您好!
Pet Theory 对您的工作给予了高度评价。您为团队增光不少。
现在您已经完成了这项任务,我想和您谈谈在新项目中担任更高级职位的事宜。
Melody
总经理
Computer Consulting Inc.
|
后续步骤/了解详情
Google Cloud 培训和认证
…可帮助您充分利用 Google Cloud 技术。我们的课程会讲解各项技能与最佳实践,可帮助您迅速上手使用并继续学习更深入的知识。我们提供从基础到高级的全方位培训,并有点播、直播和虚拟三种方式选择,让您可以按照自己的日程安排学习时间。各项认证可以帮助您核实并证明您在 Google Cloud 技术方面的技能与专业知识。
上次更新手册的时间:2024 年 2 月 1 日
上次测试实验的时间:2023 年 9 月 20 日
版权所有 2025 Google LLC 保留所有权利。Google 和 Google 徽标是 Google LLC 的商标。其他所有公司名和产品名可能是其各自相关公司的商标。