Almacena en búfer las solicitudes HTTP con Cloud Tasks

1. Introducción

c6ac6ed05292f13e.png

Cloud Tasks es un servicio de filas completamente administrado para administrar la ejecución, el envío y la entrega de una gran cantidad de tareas.

Cloud Tasks te permite separar trabajos, llamados tareas, que se pueden realizar de forma independiente (p. ej., una tarea para actualizar una entrada de la base de datos) fuera del flujo principal de la aplicación y enviarlos para que se procesen de forma asíncrona con los controladores que crees.

La tarea descargada se agrega a una cola, que mantiene la tarea hasta que se ejecuta con éxito o falla. Según la configuración, la cola también puede actuar como un control de flujo de envío. Debes crear y configurar la cola que el servicio Cloud Tasks administrará. Una vez que se agregan las tareas, la cola las envía y se asegura de que los trabajadores las procesen de manera confiable.

d59ffe8d34138c88.png

Estas son algunas de las principales funciones de Cloud Tasks:

  • Destinos HTTP: Agrega tareas que se orienten a cualquier servicio HTTP que se ejecute en Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions o en sistemas locales de manera segura con la autenticación OAuth/OIDC estándar de la industria.
  • Anulación de duplicación de tareas: Solo se despacharán una vez las tareas agregadas varias veces.
  • Entrega garantizada: Se garantiza que las tareas se entregarán al menos una vez, y la mayoría de las tareas se entregan exactamente una vez.
  • Controles de velocidad y reintentos: Para controlar la ejecución, configura la velocidad de envío de las tareas, la cantidad máxima de intentos y la cantidad mínima de tiempo de espera entre intentos.
  • Programación futura: Controla el tiempo para ejecutar una tarea.

En este codelab, primero aprenderás a crear y usar una cola de Cloud Tasks normal para tareas de destino HTTP. Luego, aprenderás a usar la anulación de URI HTTP a nivel de la cola y la nueva API de BufferTask para almacenar en búfer las solicitudes HTTP con Cloud Tasks de forma más sencilla.

Qué aprenderás

  • Cómo crear tareas de destino HTTP
  • Cómo crear tareas de destino HTTP con la nueva anulación del URI HTTP a nivel de la cola
  • Cómo cambiar las tareas pendientes con la nueva anulación del URI HTTP a nivel de la cola
  • Cómo almacenar en búfer solicitudes HTTP con mayor facilidad con la nueva API de BufferTask

2. Configuración y requisitos

Cómo configurar el entorno a tu propio ritmo

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla cuando quieras.
  • El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Cloud genera automáticamente una cadena única. Por lo general, no importa cuál sea. En la mayoría de los codelabs, deberás hacer referencia al ID de tu proyecto (suele identificarse como PROJECT_ID). Si no te gusta el ID que se generó, podrías generar otro aleatorio. También puedes probar uno propio y ver si está disponible. No se puede cambiar después de este paso y se usa el mismo durante todo el proyecto.
  • Recuerda que hay un tercer valor, un número de proyecto, que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.
  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no costará mucho, tal vez nada. Para cerrar recursos y evitar que se generen cobros más allá de este instructivo, puedes borrar los recursos que creaste o borrar el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de $300.

Inicie Cloud Shell

Si bien Google Cloud y Spanner se pueden operar de manera remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.

En Google Cloud Console, haz clic en el ícono de Cloud Shell en la barra de herramientas en la parte superior derecha:

55efc1aaa7a4d3ad.png

El aprovisionamiento y la conexión al entorno deberían tomar solo unos minutos. Cuando termine el proceso, debería ver algo como lo siguiente:

7ffe5cbb04455448.png

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Todo tu trabajo en este codelab se puede hacer en un navegador. No es necesario que instales nada.

3. Crea una cola regular para las tareas de destino HTTP

En este primer paso, aprenderás a crear una cola normal de Cloud Tasks y a agregarle tareas HTTP para orientarlas a un servicio de Cloud Run.

d4f09a342c8eab.png

¿Qué son las tareas de destino HTTP?

Las tareas de destino HTTP pueden orientarse a cualquier servicio HTTP que se ejecute en Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions o en sistemas locales de manera segura con la autenticación OAuth/OIDC estándar de la industria.

Implementa un servicio de Cloud Run

Primero, asegúrate de que las APIs necesarias estén habilitadas:

gcloud services enable \
  cloudtasks.googleapis.com \
  run.googleapis.com

Implementa un servicio de Cloud Run que actuará como destino de las tareas HTTP:

SERVICE1=hello1
REGION=us-central1

gcloud run deploy $SERVICE1 \
  --allow-unauthenticated \
  --image=gcr.io/cloudrun/hello \
  --region=$REGION

Crea una cola de Cloud Tasks

Crea una cola normal de Cloud Tasks:

QUEUE1=http-queue
LOCATION=us-central1

gcloud tasks queues create $QUEUE1 --location=$LOCATION

Pausa la cola de forma temporal para que puedas observar las tareas HTTP a medida que se crean:

gcloud tasks queues pause $QUEUE1 --location=$LOCATION

4. Crea y prueba una tarea HTTP

En este paso, crearás una tarea HTTP para segmentar la cola que creaste anteriormente.

Crea una tarea HTTP

Puedes crear tareas HTTP con gcloud de la siguiente manera:

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

Opcional: También puedes crear una tarea HTTP con bibliotecas cliente. Por ejemplo, puedes consultar Program.cs para ver una muestra en C# en la que una solicitud HTTP se encapsula en un Task y un TaskRequest antes de enviarse a Cloud Tasks con un 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);

Puedes ejecutarlo de la siguiente manera para crear y agregar la tarea a la cola:

dotnet run $PROJECT_ID $LOCATION $QUEUE1 $SERVICE1_URL

Prueba la tarea de HTTP

En este punto, la tarea se crea, pero aún no se ejecuta, ya que la cola está pausada. Para verificarlo, enumera las colas:

gcloud tasks queues list --location=$LOCATION

Deberías ver la cola en estado PAUSED:

QUEUE_NAME  STATE
http-queue  PAUSED

Para reanudar la cola, haz lo siguiente:

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

Verifica los registros del servicio de Cloud Run:

gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=$SERVICE1" --limit 1

Deberías ver que el servicio de Cloud Run recibió una solicitud HTTP GET de 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. Crea una fila con una configuración de enrutamiento

En este paso, aprenderás a crear una cola de Cloud Tasks con una configuración de enrutamiento para agregar una URI de HTTP anulada con la función Configuración de enrutamiento de tareas a nivel de la cola. Luego, le agregarás tareas HTTP para segmentar el primer servicio de Cloud Run y observarás que la configuración de enrutamiento anula el URI para enrutar las tareas al segundo servicio de Cloud Run.

5d1ec61a933f77.png

¿Qué es la configuración de enrutamiento de tareas a nivel de la cola?

La configuración del enrutamiento de tareas a nivel de la cola cambia el enrutamiento de tareas HTTP para toda la cola en todas las tareas pendientes y nuevas. Esto permite crear tareas con mayor facilidad, ya que no es necesario establecer el destino HTTP a nivel de la tarea, y se transfiere más control al proveedor de servicios, ya que puede establecer el destino de todas las tareas en una cola (p. ej., enrutar el tráfico a un backend diferente si el backend original está inactivo).

La siguiente configuración se puede establecer a nivel de la fila:

  • Encabezados: Los encabezados a nivel de la cola, cuando se especifican a ese nivel, insertan o actualizan encabezados para todas las tareas de la cola.
  • Método HTTP: Si se especifica a nivel de la fila, el método HTTP anulará el método HTTP de todas las tareas de la fila.
  • URI de destino: Se pueden anular de forma individual el host, la ruta de acceso, la consulta, el puerto y el esquema (HTTP o HTTPS).
  • Autorización: La configuración de OIDC/OAuth especificada a nivel de la fila anulará la configuración de OIDC/OAuth a nivel de la tarea.

Implementa un segundo servicio de Cloud Run

Implementa un segundo servicio de Cloud Run que actuará como destino de la anulación del URI HTTP más adelante:

SERVICE2=hello2
REGION=us-central1

gcloud run deploy $SERVICE2 \
  --allow-unauthenticated \
  --image=gcr.io/cloudrun/hello \
  --region=$REGION

Guarda el host de la URL del servicio para usarlo más adelante:

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

Crea una cola de Cloud Tasks con una configuración de enrutamiento

Crea una cola con una configuración de enrutamiento con la URI de HTTP anulada para el segundo servicio de Cloud Run.

QUEUE2=http-queue-uri-override

gcloud beta tasks queues create $QUEUE2 \
  --http-uri-override=host:$SERVICE2_HOST \
  --location=$LOCATION

Ten en cuenta que la anulación del URI hace referencia al segundo servicio de Cloud Run. Se anulará el host del URI original de cualquier tarea HTTP que se agregue a la cola. Puedes ver la configuración de la cola:

gcloud beta tasks queues describe $QUEUE2 --location=$LOCATION

Deberías ver que el httpTarget tiene un uriOverride que apunta al host del segundo servicio:

httpTarget:
  uriOverride:
    host: hello2-idcwffc3yq-uc.a.run.app
    pathOverride: {}
    queryOverride: {}
...

Pausa la cola de forma temporal para que puedas observar las tareas HTTP a medida que se crean:

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

6. Crea y prueba una tarea HTTP para la cola con la configuración de enrutamiento

En este paso, crearás una tarea HTTP para segmentar el primer servicio y observarás que la URI se anula por la cola para apuntar al segundo servicio.

Crea una tarea HTTP

Crea una tarea HTTP con la URL del primer servicio:

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

Prueba la tarea de HTTP

Para reanudar la cola, haz lo siguiente:

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

Deberías ver que el segundo servicio de Cloud Run (no el primero) recibió una solicitud HTTP GET de Cloud Tasks debido a la anulación:

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. Cambia las tareas pendientes con la configuración de enrutamiento

También puedes usar la configuración de enrutamiento para cambiar el URI HTTP de todas las tareas pendientes en una cola. Esto es útil si el servicio de backend deja de funcionar y deseas enrutar rápidamente a otro servicio. Veamos cómo funciona en este paso.

Vuelve a pausar la cola:

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

Crea una tarea HTTP con google.com como URL de la tarea:

gcloud tasks create-http-task \
    --queue=$QUEUE2 \
    --location=$LOCATION \
    --url=https://www.google.com \
    --method=GET

La tarea está en estado pendiente porque la cola está pausada.

Ahora, actualiza la anulación del URI HTTP para que apunte al primer servicio. Esto anulará el host de la tarea pendiente de google.com al host del primer servicio:

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

Para reanudar la cola, haz lo siguiente:

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

Deberías ver que el primer servicio de Cloud Run recibió una solicitud HTTP GET de Cloud Tasks debido a la anulación (en lugar de 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. Crea una cola para la API de BufferTask

Normalmente, creas tareas con la API de Tasks desde gcloud o las bibliotecas cliente de Tasks. Esto obliga a las aplicaciones a encapsular las solicitudes HTTP en tareas con bibliotecas cliente y también crea una dependencia entre las aplicaciones y las bibliotecas cliente de Tasks.

En este paso, verás cómo aprovechar la anulación del URI HTTP a nivel de la fila y la nueva API de BufferTask para crear tareas de destino HTTP con mayor facilidad con solo enviar una solicitud HTTP. Cualquier aplicación que pueda enviar solicitudes HTTP ahora puede crear tareas de destino HTTP.

b1606516297fc4b6.png

¿Qué es la API de BufferTask?

La API de CreateTask es la forma anterior de crear tareas y requiere que el cliente envíe un objeto Task a la API con todos los campos obligatorios establecidos.

La API de BufferTask es una nueva función que permite a los usuarios crear una tarea HTTP sin necesidad de proporcionar ninguna configuración de tarea (URL de HTTP, encabezados, autorización), lo que te permite simplemente enviar un mensaje o el cuerpo de tu solicitud a la API de Buffer.

Esto permite una integración más sencilla con los servicios, ya que Cloud Tasks ahora se puede implementar delante de tu servicio sin necesidad de realizar cambios en el código del cliente. Cualquier solicitud HTTP arbitraria que se envíe a la API de BufferTask se encapsulará como un objeto Task y se entregará al destino establecido a nivel de la cola.

Para usar la API de BufferTask, la cola debe tener establecida la configuración del URI de destino o, en otras palabras, la función Configuración de enrutamiento a nivel de la cola es un requisito previo para usar la API de BufferTask.

Crea una cola de Cloud Tasks con configuración de enrutamiento

Crea una cola con una configuración de enrutamiento que apunte al primer servicio que implementamos en el paso anterior:

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

Pausa la cola de forma temporal para que puedas observar las tareas HTTP a medida que se crean:

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

9. Almacena en búfer las solicitudes HTTP con la API de BufferTask

En este paso, almacenarás en búfer solicitudes HTTP GET o POST simples con la API de BufferTask. En segundo plano, Cloud Tasks encapsulará estas solicitudes HTTP en tareas HTTP con la configuración predeterminada de enrutamiento de la cola.

Primero, accede para obtener un token de acceso y configura algunas variables:

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"

Crea una tarea HTTP

Crea una tarea HTTP con la API de BufferTask. Observa cómo es una solicitud GET de HTTP simple sin necesidad de crear una tarea:

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

Crea otra tarea HTTP con HTTP POST y un cuerpo:

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

Opcional: También puedes crear una tarea HTTP con bibliotecas cliente. Por ejemplo, puedes consultar Program.cs para ver un ejemplo en C# en el que se envía una solicitud HTTP GET directamente a la API de BufferTask sin tener que encapsularla en un Task ni necesitar la biblioteca cliente de 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}");
}

Puedes ejecutarlo de la siguiente manera:

dotnet run $PROJECT_ID $LOCATION $QUEUE3 $ACCESS_TOKEN

La API de BufferTask se encarga de crear una tarea a partir de las solicitudes HTTP y agrega la URL de la configuración de enrutamiento de la cola para el URI.

Prueba la tarea de HTTP

Para reanudar la cola, haz lo siguiente:

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

Deberías ver que el servicio de Cloud Run recibió solicitudes HTTP GET y POST de 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. Felicitaciones

¡Felicitaciones! Completaste el codelab.

Como seguimiento, puedes probar Cloud Tasks como búfer entre Pub/Sub y Cloud Run para ver un ejemplo real de cómo estas nuevas funciones de Cloud Tasks pueden ayudar a crear fácilmente una cola de búfer entre los servicios.

Limpieza (opcional)

Para evitar que se apliquen cargos, es una buena idea limpiar los recursos.

Si no necesitas el proyecto, puedes borrarlo:

gcloud projects delete $PROJECT_ID

Si necesitas el proyecto, puedes borrar los recursos de forma individual.

Borra los servicios de Cloud Run:

gcloud run services delete $SERVICE1 --region $REGION
gcloud run services delete $SERVICE2 --region $REGION

Borra las colas de Cloud Tasks:

gcloud tasks queues delete $QUEUE1 --location=$LOCATION
gcloud tasks queues delete $QUEUE2 --location=$LOCATION
gcloud tasks queues delete $QUEUE3 --location=$LOCATION

Temas abordados

  • Cómo crear tareas de destino HTTP
  • Cómo crear tareas de destino HTTP con la nueva anulación del URI HTTP a nivel de la cola
  • Cómo cambiar las tareas pendientes con la nueva anulación del URI HTTP a nivel de la cola
  • Cómo almacenar en búfer solicitudes HTTP con mayor facilidad con la nueva API de BufferTask