Буферизация HTTP-запросов с помощью Cloud Tasks

1. Введение

c6ac6ed05292f13e.png

Cloud Tasks — это полностью управляемый сервис очередей, предназначенный для управления выполнением, распределением и доставкой большого количества задач.

Cloud Tasks позволяет выделять отдельные части работы, называемые задачами , которые могут выполняться независимо (например, задача по обновлению записи в базе данных) вне основного потока приложения, и отправлять их на асинхронную обработку с помощью созданных вами обработчиков.

Перенесенная задача добавляется в очередь , которая сохраняет задачу до тех пор, пока она не будет успешно выполнена или не произойдет сбой. В зависимости от конфигурации, очередь также может выступать в качестве контроллера потока диспетчеризации. Вы создаете и настраиваете очередь, которая затем управляется службой Cloud Tasks. После добавления задач очередь распределяет их и обеспечивает надежную обработку задач рабочими процессами.

d59ffe8d34138c88.png

К основным особенностям Cloud Tasks относятся:

  • Целевые HTTP-задачи: Добавляйте задачи, нацеленные на любой HTTP-сервис, работающий в Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions или локальных системах, безопасным способом, используя стандартную отраслевую аутентификацию OAuth/OIDC.
  • Дедупликация задач : задачи, добавленные несколько раз, будут отправлены только один раз.
  • Гарантированная доставка : Гарантируется, что задачи будут выполнены как минимум один раз, а большинство задач выполняются ровно один раз.
  • Управление скоростью и количеством повторных попыток: регулируйте выполнение, устанавливая скорость отправки задач, максимальное количество попыток и минимальное время ожидания между попытками.
  • Планирование на будущее: контроль времени выполнения задачи.

В этом практическом занятии вы сначала научитесь создавать и использовать обычную очередь Cloud Tasks для целевых HTTP-задач. Затем вы узнаете, как использовать переопределение HTTP URI на уровне очереди и новый API BufferTask для более удобной буферизации HTTP-запросов с помощью Cloud Tasks.

Что вы узнаете

  • Как создавать целевые задачи HTTP.
  • Как создавать целевые задачи HTTP с использованием нового механизма переопределения URI HTTP на уровне очереди.
  • Как изменить ожидающие задачи с помощью нового механизма переопределения HTTP URI на уровне очереди.
  • Как упростить буферизацию HTTP-запросов с помощью нового API BufferTask.

2. Настройка и требования

Настройка среды для самостоятельного обучения

  1. Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google. Вы всегда можете его изменить.
  • Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор вашего проекта (обычно обозначается как PROJECT_ID ). Если сгенерированный идентификатор вас не устраивает, вы можете сгенерировать другой случайный идентификатор. В качестве альтернативы вы можете попробовать свой собственный и посмотреть, доступен ли он. После этого шага его нельзя изменить, и он сохраняется на протяжении всего проекта.
  • К вашему сведению, существует третье значение — номер проекта , которое используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
  1. Далее вам потребуется включить оплату в консоли Cloud для использования ресурсов/API Cloud. Выполнение этого практического задания не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, вы можете удалить созданные ресурсы или удалить проект. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с ноутбука, в этом практическом занятии вы будете использовать Google Cloud Shell — среду командной строки, работающую в облаке.

В консоли Google Cloud нажмите на значок Cloud Shell на панели инструментов в правом верхнем углу:

55efc1aaa7a4d3ad.png

Подготовка и подключение к среде займут всего несколько минут. После завершения вы должны увидеть что-то подобное:

7ffe5cbb04455448.png

Эта виртуальная машина содержит все необходимые инструменты разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Вся работа в этом практическом задании может выполняться в браузере. Вам не нужно ничего устанавливать.

3. Создайте обычную очередь для задач, ориентированных на HTTP-цели.

На первом этапе вы узнаете, как создать обычную очередь задач Cloud Tasks и добавить в нее HTTP-задачи для службы Cloud Run.

d4f09a342c8eab.png

Что такое целевые задачи HTTP?

Целевые задачи HTTP могут быть нацелены на любой HTTP-сервис, работающий в Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions или локальных системах, с использованием стандартной отраслевой аутентификации OAuth/OIDC.

Разверните сервис 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:

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 прежде чем быть отправленным в Cloud Tasks с помощью CloudTasksClient :

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 получила HTTP GET-запрос от Cloud Tasks:

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 с конфигурацией маршрутизации, позволяющей добавить переопределение URI HTTP с помощью функции « Конфигурация маршрутизации задач на уровне очереди» . Затем вы добавите в нее задачи HTTP, ориентированные на первую службу Cloud Run, и заметите, что конфигурация маршрутизации переопределяет URI для перенаправления задач на вторую службу Cloud Run.

5d1ec61a933f77.png

Что такое конфигурация маршрутизации задач на уровне очереди?

Настройка маршрутизации задач на уровне очереди изменяет маршрутизацию 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

Сохраните хост URL-адреса сервиса для последующего использования:

SERVICE2_URL=$(gcloud run services describe $SERVICE2 --region $REGION --format 'value(status.url)')
SERVICE2_HOST=$(echo $SERVICE2_URL | sed 's,http[s]*://,,g')

Создайте очередь облачных задач с настройкой маршрутизации.

Создайте очередь с конфигурацией маршрутизации, включающей переопределение 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-задачу с URL-адресом первого сервиса:

gcloud tasks create-http-task \
    --queue=$QUEUE2 \
    --location=$LOCATION \
    --url=$SERVICE1_URL \
    --method=GET

Проверьте выполнение задачи HTTP.

Возобновить выполнение задания в очереди:

gcloud tasks queues resume $QUEUE2 --location=$LOCATION

Вы должны увидеть, что вторая (а не первая) служба Cloud Run получила HTTP GET-запрос от Cloud Tasks из-за переопределения:

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

Создайте HTTP-задачу, указав google.com в качестве URL-адреса задачи:

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

Вы должны увидеть, что первая служба Cloud Run получила HTTP GET-запрос от Cloud Tasks из-за переопределения (вместо google.com ):

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. Создайте очередь для API BufferTask.

Обычно задачи создаются с помощью API Tasks, либо из gcloud , либо из клиентских библиотек Tasks. Это нагружает приложения необходимостью оборачивать HTTP-запросы в задачи с помощью клиентских библиотек, а также создает зависимость между приложениями и клиентскими библиотеками Tasks.

На этом шаге вы узнаете, как использовать преимущества переопределения HTTP URI на уровне очереди и нового API BufferTask для более простого создания целевых задач HTTP путем простой отправки HTTP-запроса. Теперь любое приложение, способное отправлять HTTP-запросы, может создавать целевые задачи HTTP.

b1606516297fc4b6.png

Что такое API BufferTask?

API CreateTask — это устаревший способ создания задач, требующий от клиента отправки объекта Task в API со всеми необходимыми полями.

API BufferTask — это новая функция, которая позволяет пользователям создавать HTTP-задачи без необходимости предоставления какой-либо конфигурации задачи (HTTP-URL, заголовки, авторизация), что позволяет просто отправить сообщение или тело запроса в API Buffer.

Это упрощает интеграцию с сервисами, поскольку теперь облачные задачи можно развертывать перед вашим сервисом без необходимости внесения каких-либо изменений в код на стороне клиента. Любой произвольный HTTP-запрос, отправленный в API BufferTask, будет обернут в объект Task и доставлен в пункт назначения, заданный на уровне очереди.

Для использования API BufferTask необходимо, чтобы для очереди была задана конфигурация целевого URI, или, другими словами, для использования API BufferTask требуется наличие функции конфигурации маршрутизации на уровне очереди .

Создайте очередь облачных задач с настройкой маршрутизации.

Создайте очередь с конфигурацией маршрутизации, указывающей на первый сервис, развернутый на предыдущем шаге:

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. Буферизация HTTP-запросов с помощью API BufferTask.

На этом этапе вы будете буферизовать простые HTTP GET или POST запросы с помощью API BufferTask. 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-задачу

Создайте HTTP-задачу с помощью API BufferTask. Обратите внимание, что это простой HTTP GET-запрос, не требующий создания задачи:

curl -X GET "$TASKS_QUEUES_API/$QUEUE3/tasks:buffer" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Создайте еще одну HTTP-задачу с HTTP POST-запросом и телом:

curl -X POST "$TASKS_QUEUES_API/$QUEUE3/tasks:buffer" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d "{'message': 'Hello World'}"

Дополнительно: Вы также можете создать HTTP-задачу с использованием клиентских библиотек. Например, вы можете посмотреть пример на C# в файле Program.cs , где HTTP GET-запрос отправляется непосредственно в API BufferTask без необходимости оборачивать его в 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

API BufferTask отвечает за создание задачи из HTTP-запросов и добавляет URL-адрес из настроек маршрутизации очереди для URI.

Проверьте выполнение задачи HTTP.

Возобновить выполнение задания в очереди:

gcloud tasks queues resume $QUEUE3 --location=$LOCATION

Вы должны увидеть, что служба Cloud Run получила HTTP-запросы GET и POST от Cloud Tasks:

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. Поздравляем!

Поздравляем, вы завершили практическое занятие!

В качестве продолжения вы можете попробовать использовать 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

Удалите очереди облачных задач:

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 на уровне очереди.
  • Как упростить буферизацию HTTP-запросов с помощью нового API BufferTask.