关于此 Codelab
1. 概览
在本实验中,您将创建一个 Eventarc 触发器,用于将 Pub/Sub 主题连接到 Workflows 服务。Eventarc 让您可以将服务与服务通信分离开来,使您的解决方案更具可扩展性和事件驱动型。您将创建一个工作流,其中包含执行业务流程的多个步骤,以计算在 Cymbal Eats 下单的客户奖励积分。工作流将向 GKE Autopilot 上运行的应用发送多个请求,并向 Pub/Sub 主题发布消息,通知订单服务应用计算的奖励积分。
什么是 GKE Autopilot?
GKE Autopilot 是 GKE 中的一种操作模式,在这种模式下,Google 会管理您的集群配置,包括节点、扩缩、安全性和其他预配置的设置。Autopilot 集群已经过优化,可运行大多数生产工作负载,并根据您的 Kubernetes 清单预配计算资源。简化的配置遵循了 GKE 在集群和工作负载设置、可伸缩性和安全性方面的最佳实践和建议。如需查看内置设置的列表,请参阅 Autopilot 和标准对比表格。
使用 GKE Standard 时,用户负责管理工作器节点和节点池配置,其余工作由 GKE 处理。
在 GKE 标准模式下运行时,客户与 Google 的责任
使用 GKE Autopilot 时,Google 会负责节点池配置和管理。这使您可以专注于在集群上运行的应用和服务。
什么是 Eventarc?
借助 Eventarc,您可以构建事件驱动型架构,而无需实现、自定义或维护底层基础架构。Eventarc 提供了一个标准化解决方案,用于管理分离微服务之间的状态更改流(称为事件)。触发后,Eventarc 会通过 Pub/Sub 订阅将这些事件路由到各个目的地(例如Workflows、Cloud Run)同时管理交付、安全性、授权、可观测性和错误处理。
Google 事件提供方
- 超过 90 家 Google Cloud 提供商。这些提供方直接从来源(例如 Cloud Storage)发送事件,或通过 Cloud Audit Logs 条目发送事件。
- Pub/Sub 提供方。这些提供程序使用 Pub/Sub 消息将事件发送到 Eventarc。
第三方提供商
第三方提供商是指提供 Eventarc 来源的非 Google 实体。
Eventarc 触发器
- Cloud Pub/Sub 事件。Eventarc 可由发布到 Pub/Sub 主题的消息触发。
- Cloud Audit Logs (CAL) 事件。Cloud Audit Logs 可为每个 Cloud 项目、文件夹和组织提供管理员活动和数据访问审核日志。
- 直接事件:Eventarc 可由各种直接事件触发,例如 Cloud Storage 存储分区的更新或 Firebase Remote Config 模板的更新。
事件目的地
- Workflows
- Cloud Run
- GKE
- Cloud Functions( 第 2 代)
什么是 Workflows?
Workflows 是一项全代管式服务,您可利用这种服务集成微服务、任务和 API。Workflows 是一项无服务器服务,可根据您的需求进行扩缩。
Workflows 用例:
- 事件驱动型工作流对定义的触发器执行。例如,当提交新订单并想计算客户积分时。或者,当订单取消时,可以发布事件,所有感兴趣的服务都将处理该事件。
- 批处理作业工作流使用 Cloud Scheduler 定期运行作业。例如,夜间作业会检查处于失败状态的菜单项并将其删除。
Workflows 非常适合用于编排服务的工作流。您可以自动执行最长一年的等待和重试流程。
工作流程的优势:
- 配置胜过代码:通过将逻辑移至配置而非编写代码来减少技术债务。
- 简化架构。借助有状态工作流,您可以直观呈现和监控复杂的服务集成,而无需其他依赖项。
- 兼顾可靠性和容错能力。利用默认或自定义的重试逻辑以及错误处理功能控制故障,即使其他系统发生故障,也能通过将每个步骤检查点到 Cloud Spanner 来帮助跟踪进度。
- 零维护。根据需要进行扩展:无需修补或维护任何内容。您只需在工作流运行时付费,在等待或处于非活动状态时无需支付任何费用。
在本实验中,您将配置一个事件驱动型工作流。
学习内容
在本实验中,您将学习如何完成以下操作:
- 配置 Pub/Sub 主题和 Eventarc 以触发工作流
- 配置工作流,以便对在 GKE Autopilot 上运行的应用进行 API 调用
- 配置工作流以将消息发布到 Pub/Sub
- 如何在 Cloud Logging 中使用 gcloud CLI 查询 Workflows 结构化日志
前提条件
- 本实验假定您熟悉 Cloud 控制台和 Cloud Shell 环境。
- 已有 GKE 和 Cloud Pub/Sub 经验有帮助,但并非必需。
2. 设置和要求
Cloud 项目设置
- 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个。
- 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
- 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常您不在乎这是什么在大多数 Codelab 中,您都需要引用项目 ID(它通常标识为
PROJECT_ID
)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且该 ID 在项目期间会一直保留。 - 此外,还有第三个值,即某些 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档。
- 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有费用的话)。如需关停资源,以免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除整个项目。Google Cloud 的新用户符合参与 $300 USD 免费试用计划的条件。
环境设置
点击搜索栏右侧的图标,激活 Cloud Shell。
克隆代码库并导航到该目录,将下面的命令复制并粘贴到终端中,然后按 Enter 键:
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/customer-service
通过运行 gke-lab-setup.sh
部署所需的依赖项
系统将创建以下资源:
- AlloyDB 集群和实例
- GKE Autopilot 集群
./gke-lab-setup.sh
如果系统提示您授权,请点击“授权”以继续。
设置过程大约需要 10 分钟。
等待脚本完成,并在运行其他步骤之前看到以下输出。
NAME: client-instance ZONE: us-central1-c MACHINE_TYPE: e2-medium PREEMPTIBLE: INTERNAL_IP: 10.128.0.9 EXTERNAL_IP: 35.232.109.233 STATUS: RUNNING
3. GKE Autopilot 集群
查看 GKE Autopilot 集群
设置项目环境变量:
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')
作为初始设置的一部分,集群是使用以下命令创建的(您无需运行此命令):
gcloud container clusters create-auto $CLUSTER_NAME --region $REGION
运行以下命令以查看创建的 GKE Autopilot 集群:
gcloud container clusters list
示例输出:
运行以下命令以存储集群的凭据:
CLUSTER_NAME=rewards-cluster
REGION=us-central1
gcloud container clusters get-credentials $CLUSTER_NAME --region=$REGION
部署应用
接下来,您将部署客户服务应用。这是一种基于 Java 的微服务,它使用 Quarkus 框架。
转到 cymbal-eats/customer-service
文件夹,运行以下命令以构建并上传容器映像:
./mvnw clean package -DskipTests
export CUSTOMER_SERVICE_IMAGE=gcr.io/$PROJECT_ID/customer-service:1.0.0
gcloud builds submit --tag $CUSTOMER_SERVICE_IMAGE .
设置 AlloyDB 专用 IP 地址:
export DB_HOST=$(gcloud beta alloydb instances describe customer-instance \
--cluster=customer-cluster \
--region=$REGION \
--format=json | jq \
--raw-output ".ipAddress")
echo $DB_HOST
运行以下命令,创建 Kubernetes Secrets 对象以存储数据库凭据,客户服务应用将使用这些凭据连接到数据库:
DB_NAME=customers
DB_USER=postgres
DB_PASSWORD=password123
kubectl create secret generic gke-alloydb-secrets \
--from-literal=database=$DB_NAME \
--from-literal=username=$DB_USER \
--from-literal=password=$DB_PASSWORD \
--from-literal=db_host=$DB_HOST
运行以下命令以替换 Deployment.yaml 文件中的 CUSTOMER_SERVICE_IMAGE:
sed "s@CUSTOMER_SERVICE_IMAGE@$CUSTOMER_SERVICE_IMAGE@g" deployment.yaml.tmpl > customer-service-deployment.yaml
运行以下命令以部署应用:
kubectl apply -f customer-service-deployment.yaml
应用需要一些时间才能转换为“正在运行”状态。
查看部署规范文件:
deployment.yaml.tmpl
以下是配置的一部分,用于指定运行此应用所需的资源。
spec: containers: - name: customer-service image: CUSTOMER_SERVICE_IMAGE resources: requests: cpu: 250m memory: 512Mi ephemeral-storage: 512Mi limits: cpu: 500m memory: 1024Mi ephemeral-storage: 1Gi
运行以下命令,创建将在工作流中使用的外部 IP:
SERVICE_NAME=customer-service
kubectl expose deployment $SERVICE_NAME \
--type LoadBalancer --port 80 --target-port 8080
运行以下命令以验证已创建的资源:
kubectl get all
示例输出:
4. 查看工作流程
Workflows 核心概念
工作流包含使用 Workflows 语法(YAML 或 JSON)描述的一系列步骤。
创建工作流后,系统将执行部署,这使得工作流已准备好执行。
执行是指工作流定义中包含的逻辑的单次运行。尚未执行的工作流不会产生费用。所有工作流执行都是独立的,并且该产品的快速扩缩功能支持大量并发执行。
执行控制措施
- 步骤 - 如需创建工作流,您可以使用 Workflows 语法定义所需的
steps
和执行顺序。每个工作流必须至少有一个步骤。 - 条件 - 您可以使用
switch
块作为选择机制,允许表达式的值控制工作流的执行流程。 - 迭代 - 您可以使用
for
循环对一系列数字或一组数据(例如列表或映射)进行迭代。 - 子工作流 - 子工作流的运行方式与编程语言中的例程或函数类似,你可以封装工作流将多次重复的一个或一组步骤。
触发执行
- 手动 - 您可以通过 Google Cloud 控制台或命令行(使用 Google Cloud CLI)管理工作流。
- 程序化 - 适用于 Workflows API 或 REST API 的 Cloud 客户端库可用于管理工作流。
- 计划 - 您可以使用 Cloud Scheduler 按照特定的计划运行工作流。
运行时参数
您可以通过向主工作流添加 params
字段(位于主代码块中)来访问在运行时传递的数据。main 代码块接受属于任何有效 JSON 数据类型的单个参数。params 字段为工作流用来存储您传入数据的变量命名。
工作流逻辑
如果客户不存在,工作流程将先进行 API 调用以创建客户,然后更新奖励积分。工作流程会根据订单总金额选择调节系数,以便计算客户的奖励积分。有关详情,请参阅以下示例。
- calculate_multiplier: switch: - condition: ${totalAmount < 10} steps: - set_multiplier1: assign: - multiplier: 2 - condition: ${totalAmount >= 10 and totalAmount < 25} steps: - set_multiplier2: assign: - multiplier: 3 - condition: ${totalAmount >= 25} steps: - set_multiplier3: assign: - multiplier: 5 - calculate_rewards: assign: - rewardPoints: ${customerRecord.rewardPoints + multiplier}
5. 配置和部署 Workflow
运行命令以查看服务的外部 IP 地址:
kubectl get svc
示例输出:
使用之前输出中的外部 IP 的值设置下面的环境变量。
CUSTOMER_SERVICE_URL=http://$(kubectl get svc customer-service -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
替换工作流模板中的客户服务应用网址:
sed "s@CUSTOMER_SERVICE_URL@$CUSTOMER_SERVICE_URL@g" gkeRewardsWorkflow.yaml.tmpl > gkeRewardsWorkflow.yaml
为 Workflows 服务和项目环境变量设置位置:
gcloud config set workflows/location ${REGION}
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')
为工作流创建自定义服务账号,并拥有以下权限:
- Call Logging API
- 将消息发布到 PubSub 主题
export WORKFLOW_SERVICE_ACCOUNT=workflows-sa
gcloud iam service-accounts create ${WORKFLOW_SERVICE_ACCOUNT}
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:${WORKFLOW_SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
--role "roles/logging.logWriter"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member "serviceAccount:${WORKFLOW_SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com" \
--role "roles/pubsub.publisher"
部署工作流。工作流配置为使用上一步中创建的服务账号:
export WORKFLOW_NAME=rewardsWorkflow
gcloud workflows deploy ${WORKFLOW_NAME} \
--source=gkeRewardsWorkflow.yaml \
--service-account=${WORKFLOW_SERVICE_ACCOUNT}@$PROJECT_ID.iam.gserviceaccount.com
查看工作流来源和其他详细信息(“触发器”标签页)。目前没有配置任何触发器来执行此工作流。您将在下一步中进行设置。
6. 配置 Pub/Sub 主题和 Eventarc 触发器
接下来,您将创建两个 Pub/Sub 主题,并配置一个 Eventarc 触发器。
订单服务应用将向 order-topic
发布包含新订单相关信息的消息。
工作流会向 order-points-topic
发布消息,其中包含有关订单奖励积分和总金额的信息。订单服务(本实验中未部署的部分)会公开一个端点,供 order-points-topic,
的推送订阅用于更新奖励积分和每笔订单的总金额。
创建新的 Pub/Sub 主题:
export TOPIC_ID=order-topic
export ORDER_POINTS_TOPIC_ID=order-points-topic
gcloud pubsub topics create $TOPIC_ID --project=$PROJECT_ID
gcloud pubsub topics create $ORDER_POINTS_TOPIC_ID --project=$PROJECT_ID
为 Eventarc 服务设置位置:
gcloud config set eventarc/location ${REGION}
创建将供 Eventarc 触发器用于执行工作流的自定义服务账号。
export TRIGGER_SERVICE_ACCOUNT=eventarc-workflow-sa
gcloud iam service-accounts create ${TRIGGER_SERVICE_ACCOUNT}
向服务账号授予访问权限以执行工作流。
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${TRIGGER_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/workflows.invoker"
创建 Eventarc 触发器以监听 Pub/Sub 消息并将其传送到 Workflows。
gcloud eventarc triggers create new-orders-trigger \
--destination-workflow=${WORKFLOW_NAME} \
--destination-workflow-location=${REGION} \
--event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
--service-account="${TRIGGER_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--transport-topic=$TOPIC_ID
示例输出:
Creating trigger [new-orders-trigger] in project [qwiklabs-gcp-01-1a990bfcadb3], location [us-east1]...done. Publish to Pub/Sub topic [projects/qwiklabs-gcp-01-1a990bfcadb3/topics/order-topic] to receive events in Workflow [rewardsWorkflow]. WARNING: It may take up to 2 minutes for the new trigger to become active.
查看已创建的 Eventarc 触发器。
查看为触发器创建的订阅。
查看工作流程端的更改。已添加新的触发器。
7. 测试工作流
为了模拟订单服务,您需要从 Cloud Shell 向 Pub/Sub 主题发送消息,并在 Cloud 控制台中验证客户服务日志。
export TOPIC_ID=order-topic
gcloud pubsub topics publish $TOPIC_ID --message '{"userId":"id1","orderNumber":123456,"name":"Angela Jensen","email":"ajensen9090+eats@gmail.com","address":"1845 Denise St","city":"Mountain View","state":"CA","zip":"94043","orderItems":[{"id":7,"createDateTime":"2022-03-17T21:51:44.968584","itemImageURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","itemName":"Curry Plate","itemPrice":12.5,"itemThumbnailURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","spiceLevel":0,"status":"Ready","tagLine":"Spicy touch for your taste buds","updateDateTime":"2022-03-18T01:30:29.340584","inventory":8,"quantity":1}]}'
示例输出:
messageIds: - '5063709859203105'
查看工作流执行详细信息和日志。
8. 工作流结构化日志记录
该工作流配置为以 JSON 格式写入结构化日志。日志使用 Cloud Logging API、workflows.googleapis.com/Workflow
资源在日志名称 projects/${PROJECT_ID}/logs/Workflows
下写入。
查看下面的日志记录配置。
- log_totalAmount: call: sys.log args: json: orderNumber: ${order.orderNumber} totalAmount: ${totalAmount} multiplier: ${multiplier} totalRewardPoints: ${rewardPoints} orderRewardPoints: ${orderRewardPoints} severity: INFO
在 Cloud 控制台中打开日志浏览器,然后运行查询,以查找总金额超过 2 美元的已处理订单。
要显示搜索查询字段,请点击“显示查询”。
resource.type="workflows.googleapis.com/Workflow" AND
jsonPayload.totalAmount > 2 AND
timestamp >= "2023-01-01T00:00:00Z" AND
timestamp <= "2024-12-31T23:59:59Z"
示例输出:
打开 Cloud Shell,然后使用以下命令通过 gcloud CLI 读取日志。
gcloud logging read 'resource.type="workflows.googleapis.com/Workflow" AND jsonPayload.totalAmount > 2 AND timestamp >= "2023-01-01T00:00:00Z" AND timestamp <= "2023-12-31T23:59:59Z"' --limit 10 --format="table(jsonPayload.orderNumber,jsonPayload.totalAmount,jsonPayload.orderRewardPoints,jsonPayload.totalRewardPoints,jsonPayload.multiplier)"
使用 table
格式的输出示例:
运行以下命令以 JSON 格式返回日志:
gcloud logging read 'resource.type="workflows.googleapis.com/Workflow" AND jsonPayload.totalAmount > 2 AND timestamp >= "2023-01-01T00:00:00Z" AND timestamp <= "2023-12-31T23:59:59Z"' --limit 10 --format=json | jq
使用 json
格式的输出示例:
9. 查看客户记录
(可选步骤)
运行以下命令以设置客户服务网址环境变量。
CUSTOMER_SERVICE_URL=http://$(kubectl get svc customer-service -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl $CUSTOMER_SERVICE_URL/customer | jq
示例输出:
[ { "address": "1845 Denise St", "city": "Mountain View", "createDateTime": "2023-01-31T17:22:08.853644", "email": "ajensen9090+eats@gmail.com", "id": "id1", "name": "Angela Jensen", "rewardPoints": 4, "state": "CA", "updateDateTime": "2023-01-31T17:22:09.652117", "zip": "94043" } ]
运行命令以多次发布新订单,并使用 curl 命令验证客户奖励积分。
发布新订单消息:
export TOPIC_ID=order-topic
gcloud pubsub topics publish $TOPIC_ID --message '{"userId":"id1","orderNumber":123456,"name":"Angela Jensen","email":"ajensen9090+eats@gmail.com","address":"1845 Denise St","city":"Mountain View","state":"CA","zip":"94043","orderItems":[{"id":7,"createDateTime":"2022-03-17T21:51:44.968584","itemImageURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","itemName":"Curry Plate","itemPrice":12.5,"itemThumbnailURL":"https://images.unsplash.com/photo-1618449840665-9ed506d73a34?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80","spiceLevel":0,"status":"Ready","tagLine":"Spicy touch for your taste buds","updateDateTime":"2022-03-18T01:30:29.340584","inventory":8,"quantity":1}]}'
验证客户奖励积分:
curl $CUSTOMER_SERVICE_URL/customer | jq
运行以下命令来检查最新的日志:
gcloud logging read 'resource.type="workflows.googleapis.com/Workflow" AND jsonPayload.totalAmount > 2 AND timestamp >= "2023-01-01T00:00:00Z" AND timestamp <= "2023-12-31T23:59:59Z"' --limit 10 --format="table(jsonPayload.orderNumber,jsonPayload.totalAmount,jsonPayload.orderRewardPoints,jsonPayload.totalRewardPoints,jsonPayload.multiplier)"
10. 恭喜!
恭喜,您已完成此 Codelab!
所学内容:
- 如何配置 Pub/Sub 主题和 Eventarc 以触发工作流
- 如何配置工作流以对在 GKE Autopilot 上运行的应用进行 API 调用
- 如何配置工作流以将消息发布到 Pub/Sub
- 如何在 Cloud Logging 中使用 gcloud CLI 查询 Workflows 结构化日志
后续步骤:
探索其他 Cymbal Eats Codelab:
- 使用 Eventarc 触发 Cloud Workflows
- 从 Cloud Storage 触发事件处理
- 从 Cloud Run 连接到 Private CloudSQL
- 从 Cloud Run 连接到全代管式数据库
- 使用 Identity-Aware Proxy (IAP) 保护无服务器应用
- 使用 Cloud Scheduler 触发 Cloud Run 作业
- 安全地部署到 Cloud Run
- 保护 Cloud Run 入站流量
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除项目
若要避免产生费用,最简单的方法是删除您为本教程创建的项目。