1. 简介

Cloud Tasks 是一项全托管式排队服务,用于管理大量任务的执行、分派和传送。
借助 Cloud Tasks,您可以分离出在主应用流之外独立执行的部分工作(称为任务,例如更新数据库条目的任务),并使用您创建的处理程序异步处理这些工作。
已分流的任务会添加到队列中,此队列会一直保留该任务,直到任务成功执行或失败。根据配置,队列还可以充当调度流控制。您可以创建和配置队列,然后由 Cloud Tasks 服务进行管理。一旦添加任务,队列便会分派任务并确保工作器可靠地处理这些任务。

Cloud Tasks 的一些主要功能包括:
- HTTP 目标:使用行业标准 OAuth/OIDC 身份验证机制,以安全的方式添加以任何在 Compute Engine、Google Kubernetes Engine、Cloud Run、Cloud Functions 或本地系统上运行的 HTTP 服务为目标的任务。
- 任务去重:添加了多次的任务只会分派一次。
- 保证交付:系统保证任务至少交付一次,并且大多数任务只交付一次。
- 速率和重试控制:通过设置分派任务的速率、最大尝试次数以及两次尝试之间的最短等待时间来控制任务的执行。
- 未来调度:控制任务运行的时间。
在此 Codelab 中,您将首先学习如何为 HTTP 目标任务创建和使用常规 Cloud Tasks 队列。然后,您将学习如何使用队列级 HTTP URI 替换和新的 BufferTask API,以便更轻松地使用 Cloud Tasks 缓冲 HTTP 请求。
学习内容
- 如何创建 HTTP 目标任务。
- 如何使用新的队列级 HTTP URI 替换项创建 HTTP 目标任务。
- 如何使用新的队列级 HTTP URI 替换来更改待处理任务。
- 如何使用新的 BufferTask API 更轻松地缓冲 HTTP 请求。
2. 设置和要求
自定进度的环境设置
- 登录 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 美元免费试用计划的条件。
启动 Cloud Shell
虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。
在 Google Cloud 控制台 中,点击右上角工具栏中的 Cloud Shell 图标:

预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的所有工作都可以在浏览器中完成。您无需安装任何程序。
3. 为 HTTP 目标任务创建常规队列
在第一步中,您将学习如何创建常规 Cloud Tasks 队列并向其中添加 HTTP 任务,以定位 Cloud Run 服务。

什么是 HTTP 目标任务?
HTTP 目标任务可以使用行业标准 OAuth/OIDC 身份验证机制,以安全的方式发送至任何在 Compute Engine、Google Kubernetes Engine、Cloud Run、Cloud Functions 或本地系统上运行的 HTTP 服务。
部署 Cloud Run 服务
首先,确保已启用所需的 API:
gcloud services enable \ cloudtasks.googleapis.com \ run.googleapis.com
部署将充当 HTTP 任务目标的 Cloud Run 服务:
SERVICE1=hello1 REGION=us-central1 gcloud run deploy $SERVICE1 \ --allow-unauthenticated \ --image=gcr.io/cloudrun/hello \ --region=$REGION
创建 Cloud Tasks 队列
创建常规 Cloud Tasks 队列:
QUEUE1=http-queue LOCATION=us-central1 gcloud tasks queues create $QUEUE1 --location=$LOCATION
暂时暂停队列,以便您在创建 HTTP 任务时进行观察:
gcloud tasks queues pause $QUEUE1 --location=$LOCATION
4. 创建并测试 HTTP 任务
在此步骤中,您将创建一个 HTTP 任务,以定位到您之前创建的队列。
创建 HTTP 任务
您可以使用 gcloud 创建 HTTP 任务:
gcloud tasks create-http-task \
--queue=$QUEUE1 \
--location=$LOCATION \
--url=$SERVICE1_URL \
--method=GET
可选:您还可以使用客户端库创建 HTTP 任务。例如,您可以查看 Program.cs,了解一个 C# 示例,其中 HTTP 请求在通过 CloudTasksClient 发送到 Cloud Tasks 之前,会封装到 Task 和 TaskRequest 中:
var taskRequest = new CreateTaskRequest
{
Parent = new QueueName(projectId, location, queue).ToString(),
Task = new Task
{
HttpRequest = new HttpRequest
{
HttpMethod = HttpMethod.Get,
Url = url
}
}
};
var client = CloudTasksClient.Create();
var response = client.CreateTask(taskRequest);
您可以按如下方式运行该脚本,以创建任务并将其添加到队列中:
dotnet run $PROJECT_ID $LOCATION $QUEUE1 $SERVICE1_URL
测试 HTTP 任务
此时,任务已创建,但由于队列已暂停,因此尚未执行。您可以通过列出队列来验证这一点:
gcloud tasks queues list --location=$LOCATION
您应该会看到队列处于 PAUSED 状态:
QUEUE_NAME STATE http-queue PAUSED
恢复队列:
gcloud tasks queues resume $QUEUE --location=$LOCATION
查看 Cloud Run 服务的日志:
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE1" --limit 1
您应该会看到 Cloud Run 服务收到了来自 Cloud Tasks 的 HTTP GET 请求:
httpRequest: latency: 0.227597158s protocol: HTTP/1.1 remoteIp: 35.243.23.192 requestMethod: GET requestSize: '415' requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/ responseSize: '5510' serverIp: 216.239.32.53 status: 200 userAgent: Google-Cloud-Tasks
5. 创建具有路由配置的队列
在此步骤中,您将学习如何创建具有路由配置的 Cloud Tasks 队列,以使用队列级任务路由配置功能添加 HTTP URI 替换。然后,您将向其中添加 HTTP 任务,以定位第一个 Cloud Run 服务,并观察到路由配置会替换 URI,以将任务路由到第二个 Cloud Run 服务。

什么是队列级任务路由配置?
队列级任务路由配置会更改整个队列中所有待处理任务和新任务的 HTTP 任务路由。这样可以更轻松地创建任务,因为无需在任务级层设置 HTTP 目标,并且可以将更多控制权转移给服务提供商,因为他们能够设置队列中所有任务的目标(例如,如果原始后端出现故障,则将流量路由到其他后端)。
可以在队列级设置以下配置:
- 标头:如果标头是在队列级指定的,则会为队列中的所有任务插入/更新标头。
- HTTP 方法:如果在队列级指定,则会替换队列中所有任务的 HTTP 方法。
- 目标 URI:主机、路径、查询、端口、方案(HTTP 或 HTTPS)可以单独替换。
- 授权:如果在队列级指定 OIDC/OAuth 配置,则会替换任务级 OIDC/OAuth 配置。
部署第二个 Cloud Run 服务
部署第二个 Cloud Run 服务,该服务稍后将作为 HTTP URI 替换的目标:
SERVICE2=hello2 REGION=us-central1 gcloud run deploy $SERVICE2 \ --allow-unauthenticated \ --image=gcr.io/cloudrun/hello \ --region=$REGION
保存服务网址的主机以供日后使用:
SERVICE2_URL=$(gcloud run services describe $SERVICE2 --region $REGION --format 'value(status.url)') SERVICE2_HOST=$(echo $SERVICE2_URL | sed 's,http[s]*://,,g')
创建具有路由配置的 Cloud Tasks 队列
创建一个队列,其中包含将 HTTP URI 替换为第二个 Cloud Run 服务的路由配置。
QUEUE2=http-queue-uri-override gcloud beta tasks queues create $QUEUE2 \ --http-uri-override=host:$SERVICE2_HOST \ --location=$LOCATION
请注意,URI 替换是指第二个 Cloud Run 服务。添加到队列的任何 HTTP 任务的原始 URI 主机都会被替换。您可以查看队列配置:
gcloud beta tasks queues describe $QUEUE2 --location=$LOCATION
您应该会看到 httpTarget 具有指向第二个服务主机的 uriOverride:
httpTarget:
uriOverride:
host: hello2-idcwffc3yq-uc.a.run.app
pathOverride: {}
queryOverride: {}
...
暂时暂停队列,以便您在创建 HTTP 任务时进行观察:
gcloud tasks queues pause $QUEUE2 --location=$LOCATION
6. 为具有路由配置的队列创建并测试 HTTP 任务
在此步骤中,您将创建一个 HTTP 任务,以定位第一个服务,并观察到其 URI 被队列替换为指向第二个服务。
创建 HTTP 任务
使用第一个服务的网址创建 HTTP 任务:
gcloud tasks create-http-task \
--queue=$QUEUE2 \
--location=$LOCATION \
--url=$SERVICE1_URL \
--method=GET
测试 HTTP 任务
恢复队列:
gcloud tasks queues resume $QUEUE2 --location=$LOCATION
您应该会看到,由于替换,第二个(而非第一个)Cloud Run 服务收到了来自 Cloud Tasks 的 HTTP GET 请求:
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE2" --limit 1
--- httpRequest: latency: 0.228982142s protocol: HTTP/1.1 remoteIp: 35.187.132.84 requestMethod: GET requestSize: '426' requestUrl: https://hello2-idcwffc3yq-uc.a.run.app/ responseSize: '5510' serverIp: 216.239.34.53 status: 200 userAgent: Google-Cloud-Tasks
7. 更改具有路由配置的待处理任务
您还可以使用路由配置来更改队列中所有待处理任务的 HTTP URI。如果后端服务出现故障,而您想快速路由到另一项服务,此功能非常有用。我们来看看此步骤中的具体操作方式。
再次暂停队列:
gcloud tasks queues pause $QUEUE2 --location=$LOCATION
创建以 google.com 作为任务网址的 HTTP 任务:
gcloud tasks create-http-task \
--queue=$QUEUE2 \
--location=$LOCATION \
--url=https://www.google.com \
--method=GET
由于队列已暂停,任务处于待处理状态。
现在,更新 HTTP URI 替换项以指向第一个服务。这会将待处理任务的主机从 google.com 替换为第一个服务的主机:
SERVICE1_URL=$(gcloud run services describe $SERVICE1 --region $REGION --format 'value(status.url)') SERVICE1_HOST=$(echo $SERVICE1_URL | sed 's,http[s]*://,,g') gcloud beta tasks queues update $QUEUE2 \ --http-uri-override=host:$SERVICE1_HOST \ --location=$LOCATION
恢复队列:
gcloud tasks queues resume $QUEUE2 --location=$LOCATION
您应该会看到,由于替换(而不是 google.com),第一个 Cloud Run 服务收到了来自 Cloud Tasks 的 HTTP GET 请求:
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE1" --limit 1 --- httpRequest: latency: 0.228982142s protocol: HTTP/1.1 remoteIp: 35.187.132.84 requestMethod: GET requestSize: '426' requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/ responseSize: '5510' serverIp: 216.239.34.53 status: 200 userAgent: Google-Cloud-Tasks
8. 为 BufferTask API 创建队列
通常,您可以使用 Tasks API(通过 gcloud 或 Tasks 客户端库)创建任务。这会给应用带来负担,因为它们需要使用 Tasks 客户端库将 HTTP 请求封装到任务中,并且会在应用与 Tasks 客户端库之间创建依赖关系。
在此步骤中,您将了解如何利用队列级 HTTP URI 替换和新的 BufferTask API,只需发送 HTTP 请求即可更轻松地创建 HTTP 目标任务。现在,任何可以发送 HTTP 请求的应用都可以创建 HTTP 目标任务。

什么是 BufferTask API?
CreateTask API 是创建任务的旧方法,它要求客户端向 API 发送一个设置了所有必需字段的 Task 对象。
BufferTask API 是一项新功能,可让用户创建 HTTP 任务,而无需提供任何任务配置(HTTP 网址、标头、授权),从而让您只需将消息或请求正文发送到 Buffer API 即可。
这样一来,Cloud Tasks 便可部署在服务的前端,而无需在客户端进行任何代码更改,从而更轻松地与服务集成。发送到 BufferTask API 的任何任意 HTTP 请求都将封装为 Task 对象,并传递到队列级层设置的目标位置。
如需使用 BufferTask API,队列需要设置目标 URI 配置,换句话说,队列级路由配置功能是使用 BufferTask API 的前提条件。
创建具有路由配置的 Cloud Tasks 队列
创建一个队列,其路由配置指向我们在上一步中部署的第一个服务:
SERVICE1=hello1 SERVICE1_URL=$(gcloud run services describe $SERVICE1 --region $REGION --format 'value(status.url)') SERVICE1_HOST=$(echo $SERVICE1_URL | sed 's,http[s]*://,,g') QUEUE3=http-queue-uri-override-buffer gcloud beta tasks queues create $QUEUE3 \ --http-uri-override=host:$SERVICE1_HOST \ --location=$LOCATION
暂时暂停队列,以便您在创建 HTTP 任务时进行观察:
gcloud tasks queues pause $QUEUE3 --location=$LOCATION
9. 使用 BufferTask API 缓冲 HTTP 请求
在此步骤中,您将使用 BufferTask API 缓冲简单的 HTTP GET 或 POST 请求。在底层,Cloud Tasks 会将这些 HTTP 请求封装到 HTTP 任务中,并使用队列的默认路由配置设置。
首先,登录以获取访问令牌并设置一些变量:
gcloud auth application-default login ACCESS_TOKEN=$(gcloud auth application-default print-access-token) PROJECT_ID=$(gcloud config get-value project) TASKS_QUEUES_API="https://cloudtasks.googleapis.com/v2beta3/projects/$PROJECT_ID/locations/$LOCATION/queues"
创建 HTTP 任务
使用 BufferTask API 创建 HTTP 任务。请注意,这是一个简单的 HTTP GET 请求,无需创建任务:
curl -X GET "$TASKS_QUEUES_API/$QUEUE3/tasks:buffer" \ -H "Authorization: Bearer $ACCESS_TOKEN"
创建另一个包含 HTTP POST 和正文的 HTTP 任务:
curl -X POST "$TASKS_QUEUES_API/$QUEUE3/tasks:buffer" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{'message': 'Hello World'}"
可选:您还可以使用客户端库创建 HTTP 任务。例如,您可以查看 Program.cs 中的 C# 示例,其中直接向 BufferTask API 发送 HTTP GET 请求,而无需将其封装到 Task 中,也不需要 Cloud Tasks 的客户端库:
var BufferTaskApiUrl = $"https://cloudtasks.googleapis.com/v2beta3/projects/{ProjectId}/locations/{Location}/queues/{Queue}/tasks:buffer";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {AccessToken}");
var response = await client.GetAsync(BufferTaskApiUrl);
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Response: {content}");
}
您可以按如下方式运行它:
dotnet run $PROJECT_ID $LOCATION $QUEUE3 $ACCESS_TOKEN
BufferTask API 会负责根据 HTTP 请求创建任务,并为 URI 添加来自队列的路由配置设置的网址。
测试 HTTP 任务
恢复队列:
gcloud tasks queues resume $QUEUE3 --location=$LOCATION
您应该会看到 Cloud Run 服务收到了来自 Cloud Tasks 的 HTTP GET 和 POST 请求:
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE1" --limit 4
--- httpRequest: latency: 0.002279292s protocol: HTTP/1.1 remoteIp: 35.243.23.42 requestMethod: POST requestSize: '777' requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/ responseSize: '5450' serverIp: 216.239.32.53 status: 200 userAgent: Google-Cloud-Tasks ... httpRequest: latency: 0.228982142s protocol: HTTP/1.1 remoteIp: 35.187.132.84 requestMethod: GET requestSize: '426' requestUrl: https://hello1-idcwffc3yq-uc.a.run.app/ responseSize: '5510' serverIp: 216.239.34.53 status: 200 userAgent: Google-Cloud-Tasks
10. 恭喜
恭喜,您已完成此 Codelab!
接下来,您可以尝试 Cloud Tasks 作为 Pub/Sub 和 Cloud Run 之间的缓冲区,了解 Cloud Tasks 的这些新功能如何帮助您轻松地在服务之间创建缓冲区队列。
清理(可选)
为避免产生费用,建议您清理资源。
如果您不需要该项目,只需将其删除即可:
gcloud projects delete $PROJECT_ID
如果您需要保留项目,则可以单独删除资源。
删除 Cloud Run 服务:
gcloud run services delete $SERVICE1 --region $REGION gcloud run services delete $SERVICE2 --region $REGION
删除 Cloud Tasks 队列:
gcloud tasks queues delete $QUEUE1 --location=$LOCATION gcloud tasks queues delete $QUEUE2 --location=$LOCATION gcloud tasks queues delete $QUEUE3 --location=$LOCATION
所学内容
- 如何创建 HTTP 目标任务。
- 如何使用新的队列级 HTTP URI 替换项创建 HTTP 目标任务。
- 如何使用新的队列级 HTTP URI 替换来更改待处理任务。
- 如何使用新的 BufferTask API 更轻松地缓冲 HTTP 请求。