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
部署一项 Cloud Run 服务,该服务将作为 HTTP 任务的目标:
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 任务。例如,您可以查看 C# 示例的 Program.cs
,其中 HTTP 请求会先封装到 Task
和 TaskRequest
中,然后再使用 CloudTasksClient
发送到 Cloud Tasks:
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 覆盖。然后,您将向该 Cloud Run 添加 HTTP 任务以定位第一个 Cloud Run 服务,并观察到路由配置会替换 URI,以便将任务路由到第二个 Cloud Run 服务。
什么是队列级任务路由配置?
队列级任务路由配置会针对所有待处理任务和新任务,更改整个队列的 HTTP 任务路由。这样可以更轻松地创建任务,因为无需在任务级别设置 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 队列
创建一个队列,在其中配置具有指向第二个 Cloud Run 服务的 HTTP URI 覆盖的路由配置。
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 客户端库创建任务。这会使应用使用客户端库将 HTTP 请求封装到 Tasks 中,并且还会在应用和 Tasks 客户端库之间产生依赖关系。
在此步骤中,您将了解如何利用队列级 HTTP URI 替换和新的 BufferTask API,通过发送 HTTP 请求来更轻松地创建 HTTP 目标任务。现在,任何可以发送 HTTP 请求的应用都可以创建 HTTP 目标任务。
什么是 BufferTask API?
CreateTask API 是创建任务的旧方法,它要求客户端向 API 发送一个任务对象,并设置所有必填字段。
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 任务。例如,您可以查看 C# 示例的 Program.cs
,在该示例中,HTTP GET 请求会直接发送到 BufferTask API,而无需将其封装到 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 请求。