Armazenar solicitações HTTP em buffer com o Cloud Tasks

1. Introdução

c6ac6ed05292f13e.png

O Cloud Tasks é um serviço de enfileiramento totalmente gerenciado para administrar a execução, o envio e a entrega de um grande número de tarefas.

O Cloud Tasks permite separar trabalhos, chamados de tarefas, que podem ser executados de forma independente (por exemplo, uma tarefa para atualizar uma entrada no banco de dados) fora do fluxo principal do aplicativo e enviá-los para processamento, de forma assíncrona, usando gerenciadores criados por você.

A tarefa descarregada é adicionada a uma fila, que mantém a tarefa até que ela seja executada com sucesso ou até que ocorra uma falha. Com base na configuração, a fila também pode atuar como um controle de fluxo de envio. Você cria e configura a fila, que é gerenciada pelo serviço Cloud Tasks. Depois que as tarefas são adicionadas, a fila as envia e garante que os workers as processem de maneira confiável.

d59ffe8d34138c88.png

Alguns dos principais recursos do Cloud Tasks são:

  • Destinos HTTP:adicione tarefas direcionadas a qualquer serviço HTTP em execução no Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions ou sistemas locais de maneira segura usando a autenticação OAuth/OIDC padrão do setor.
  • Eliminação de duplicação de tarefas: tarefas adicionadas várias vezes serão enviadas apenas uma vez.
  • Entrega garantida: as tarefas são entregues pelo menos uma vez, e a maioria das tarefas é entregue exatamente uma vez.
  • Controles de taxa e novas tentativas: controle a execução definindo a taxa de envio das tarefas, o número máximo de tentativas e o tempo mínimo de espera entre elas.
  • Programação futura:controle o horário em que uma tarefa é executada.

Neste codelab, você vai aprender a criar e usar uma fila normal do Cloud Tasks para tarefas de destino HTTP. Em seguida, você vai aprender a usar a substituição de URI HTTP no nível da fila e a nova API BufferTask para armazenar solicitações HTTP em buffer mais facilmente com o Cloud Tasks.

O que você vai aprender

  • Como criar tarefas de destino HTTP.
  • Como criar tarefas de destino HTTP com a nova substituição de URI HTTP no nível da fila.
  • Como alterar as tarefas pendentes com a nova substituição de URI HTTP no nível da fila.
  • Como armazenar solicitações HTTP em buffer mais facilmente com a nova API BufferTask.

2. Configuração e requisitos

Configuração de ambiente personalizada

  1. Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • O Nome do projeto é o nome de exibição para os participantes do projeto. É uma string de caracteres não usada pelas APIs do Google e pode ser atualizada quando você quiser.
  • O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser mudado após a definição. O console do Cloud gera automaticamente uma string exclusiva. Em geral, não importa o que seja. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, normalmente identificado como PROJECT_ID. Se você não gostar do ID gerado, crie outro aleatório. Se preferir, teste o seu e confira se ele está disponível. Ele não pode ser mudado após essa etapa e permanece durante o projeto.
  • Para sua informação, há um terceiro valor, um Número do projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
  1. Em seguida, ative o faturamento no console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não vai ser muito cara, se tiver algum custo. Para encerrar os recursos e evitar cobranças além deste tutorial, exclua os recursos criados ou exclua o projeto. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Iniciar o Cloud Shell

Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.

No Console do Google Cloud, clique no ícone do Cloud Shell na barra de ferramentas superior à direita:

55efc1aaa7a4d3ad.png

O provisionamento e a conexão com o ambiente levarão apenas alguns instantes para serem concluídos: Quando o processamento for concluído, você verá algo como:

7ffe5cbb04455448.png

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Neste codelab, todo o trabalho pode ser feito com um navegador. Você não precisa instalar nada.

3. Criar uma fila regular para tarefas de destino HTTP

Nesta primeira etapa, você vai aprender a criar uma fila normal do Cloud Tasks e adicionar tarefas HTTP a ela para direcionar a um serviço do Cloud Run.

d4f09a342c8eab.png

O que são as tarefas de destino HTTP?

As tarefas de destino HTTP podem ser direcionadas a qualquer serviço HTTP em execução no Compute Engine, Google Kubernetes Engine, Cloud Run, Cloud Functions ou sistemas locais de maneira segura usando a autenticação OAuth/OIDC padrão do setor.

Implantar um serviço do Cloud Run

Primeiro, verifique se as APIs necessárias estão ativadas:

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

Implante um serviço do Cloud Run que servirá como destino das tarefas HTTP:

SERVICE1=hello1
REGION=us-central1

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

Criar uma fila do Cloud Tasks

Crie uma fila normal do Cloud Tasks:

QUEUE1=http-queue
LOCATION=us-central1

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

Pause a fila temporariamente para observar tarefas HTTP à medida que são criadas:

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

4. Criar e testar uma tarefa HTTP

Nesta etapa, você criará uma tarefa HTTP para direcionar à fila criada anteriormente.

Criar uma tarefa HTTP

É possível criar tarefas HTTP usando gcloud:

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

Opcional: você também pode criar uma tarefa HTTP com bibliotecas de cliente. Por exemplo, é possível verificar o Program.cs para ver uma amostra de C# em que uma solicitação HTTP é agrupada em um Task e um TaskRequest antes de ser enviada para o Cloud Tasks com um 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);

Você pode executá-la desta maneira para criar e adicionar a tarefa à fila:

dotnet run $PROJECT_ID $LOCATION $QUEUE1 $SERVICE1_URL

Testar a tarefa HTTP

Nesse ponto, a tarefa está criada, mas ainda não foi executada, porque a fila está pausada. Para confirmar, liste as filas:

gcloud tasks queues list --location=$LOCATION

A fila será exibida no estado PAUSED:

QUEUE_NAME  STATE
http-queue  PAUSED

Retome a fila:

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

Verifique os registros do serviço do Cloud Run:

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

Você verá que o serviço do Cloud Run recebeu uma solicitação HTTP GET do 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. Criar uma fila com uma configuração de roteamento

Nesta etapa, você vai aprender a criar uma fila do Cloud Tasks com uma configuração de roteamento para adicionar uma substituição de URI HTTP usando o recurso Configuração de roteamento de tarefas no nível da fila. Em seguida, você vai adicionar tarefas HTTP a ele para direcionar ao primeiro serviço do Cloud Run e observar que a configuração de roteamento substitui o URI para rotear as tarefas para o segundo serviço do Cloud Run.

5d1ec61a933f77.png

O que é a configuração de roteamento de tarefas no nível da fila?

A configuração de roteamento de tarefas em nível de fila altera o roteamento de tarefas HTTP de toda a fila para todas as tarefas pendentes e novas. Isso facilita a criação de tarefas porque o destino HTTP não precisa ser definido no nível da tarefa e transfere mais controle para o provedor de serviços, já que ele pode definir o destino de todas as tarefas em uma fila (por exemplo, rotear o tráfego para um back-end diferente se o back-end original estiver inativo).

A seguinte configuração pode ser definida no nível da fila:

  • Cabeçalhos: os cabeçalhos no nível da fila, quando especificados no nível da fila, serão inseridos e atualizados para todas as tarefas na fila.
  • Método HTTP: quando especificado no nível da fila, o método HTTP substitui o método HTTP para todas as tarefas na fila.
  • URI de destino: host, caminho, consulta, porta e esquema (HTTP ou HTTPS) podem ser modificados individualmente.
  • Autorização: a configuração do OIDC/OAuth quando especificada no nível da fila substitui a configuração do OIDC/OAuth no nível da tarefa.

Implantar um segundo serviço do Cloud Run

Implante um segundo serviço do Cloud Run que servirá como destino da substituição do URI HTTP depois:

SERVICE2=hello2
REGION=us-central1

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

Salve o host do URL do serviço para mais tarde:

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

Criar uma fila do Cloud Tasks com uma configuração de roteamento

Crie uma fila com uma configuração de roteamento com substituição de URI HTTP para o segundo serviço do Cloud Run.

QUEUE2=http-queue-uri-override

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

A substituição do URI se refere ao segundo serviço do Cloud Run. Qualquer tarefa HTTP adicionada à fila terá o host de URI original substituído. Veja a configuração da fila:

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

Você vai notar que o httpTarget tem um uriOverride que aponta para o host do segundo serviço:

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

Pause a fila temporariamente para observar tarefas HTTP à medida que são criadas:

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

6. Criar e testar uma tarefa HTTP para a fila com a configuração de roteamento

Nesta etapa, você criará uma tarefa HTTP para direcionar ao primeiro serviço e observar que o URI é substituído pela fila para apontar para o segundo serviço.

Criar uma tarefa HTTP

Crie uma tarefa HTTP com o URL do primeiro serviço:

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

Testar a tarefa HTTP

Retome a fila:

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

Você verá que o segundo serviço do Cloud Run (não o primeiro) recebeu uma solicitação HTTP GET do Cloud Tasks devido à substituição:

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. Alterar as tarefas pendentes com a configuração de roteamento

Você também pode usar a configuração de roteamento para alterar o URI HTTP de todas as tarefas pendentes em uma fila. Isso é útil se o serviço de back-end ficar inativo e você quiser rotear rapidamente para outro serviço. Vamos conferir como isso funciona nesta etapa.

Pause a fila novamente:

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

Crie uma tarefa HTTP com google.com como o URL da tarefa:

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

A tarefa fica em estado pendente porque a fila está pausada.

Agora, atualize a substituição do URI HTTP para apontar para o primeiro serviço. Isso vai substituir o host da tarefa pendente de google.com para o host do primeiro serviço:

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

Retome a fila:

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

Você verá que o primeiro serviço do Cloud Run recebeu uma solicitação HTTP GET do Cloud Tasks devido à substituição (em vez 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. Criar uma fila para a API BufferTask

Normalmente, você cria tarefas usando a API Tasks a partir das bibliotecas de cliente do gcloud ou do Tasks. Isso sobrecarrega os aplicativos para unir solicitações HTTP no Google Tarefas usando bibliotecas de cliente e também cria uma dependência entre aplicativos e as bibliotecas de cliente do Google Tarefas.

Nesta etapa, você verá como aproveitar a substituição de URI HTTP no nível da fila e a nova API BufferTask para criar tarefas de destino HTTP com mais facilidade enviando uma solicitação HTTP. Qualquer aplicativo capaz de enviar solicitações HTTP agora pode criar tarefas de destino HTTP.

b1606516297fc4b6.png

O que é a API BufferTask?

A API CreateTask é a maneira antiga de criar tarefas e exige que o cliente envie um objeto Task para a API com todos os campos obrigatórios definidos.

A API BufferTask é um novo recurso que permite que os usuários criem uma tarefa HTTP sem precisar fornecer configurações de tarefa (URL, cabeçalhos, autorização de HTTP). Assim, você pode simplesmente enviar uma mensagem ou o corpo da solicitação para a API Buffer.

Isso facilita a integração com os serviços, já que agora o Cloud Tasks pode ser implantado na frente do seu serviço sem precisar de alterações de código no lado do cliente. Qualquer solicitação HTTP arbitrária enviada à API BufferTask será encapsulada como um objeto Task e entregue ao destino definido no nível da fila.

Para usar a API BufferTask, a fila precisa ter a configuração de URI de destino definida. Em outras palavras, o recurso Configuração de roteamento no nível da fila é um pré-requisito para usar a API BufferTask.

Criar uma fila do Cloud Tasks com configuração de roteamento

Crie uma fila com uma configuração de roteamento que aponte para o primeiro serviço implantado na etapa 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

Pause a fila temporariamente para observar tarefas HTTP à medida que são criadas:

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

9. Armazenar solicitações HTTP em buffer com a API BufferTask

Nesta etapa, você vai armazenar em buffer solicitações GET ou POST HTTP simples com a API BufferTask. Internamente, o Cloud Tasks vai unir essas solicitações HTTP em tarefas HTTP com as configurações de roteamento padrão da fila.

Primeiro, faça login para receber um token de acesso e defina algumas variáveis:

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"

Criar uma tarefa HTTP

Crie uma tarefa HTTP com a API BufferTask. Observe como é uma solicitação HTTP GET simples, sem a necessidade de criar uma Task:

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

Crie outra tarefa HTTP com POST HTTP e um corpo:

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

Opcional: você também pode criar uma tarefa HTTP com bibliotecas de cliente. Por exemplo, você pode conferir o Program.cs para uma amostra de C# em que uma solicitação HTTP GET é enviada diretamente para a API BufferTask sem precisar uni-la a um Task ou precisar da biblioteca de cliente para o 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}");
}

Você pode executá-lo da seguinte maneira:

dotnet run $PROJECT_ID $LOCATION $QUEUE3 $ACCESS_TOKEN

A API BufferTask cria uma tarefa a partir das solicitações HTTP e adiciona o URL das definições de configuração de roteamento da fila para o URI.

Testar a tarefa HTTP

Retome a fila:

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

Você verá que o serviço do Cloud Run recebeu solicitações HTTP GET e POST do 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. Parabéns

Parabéns, você concluiu o codelab.

Como acompanhamento, teste o Cloud Tasks como um buffer entre o Pub/Sub e o Cloud Run para ver um exemplo real de como esses novos recursos do Cloud Tasks podem ajudar a criar uma fila de buffer entre os serviços com facilidade.

Limpeza (opcional)

Para evitar cobranças, é uma boa ideia limpar os recursos.

Se você não precisar do projeto, basta excluí-lo:

gcloud projects delete $PROJECT_ID

Se você precisar do projeto, poderá excluir os recursos individualmente.

Exclua os serviços do Cloud Run:

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

Exclua as filas do Cloud Tasks:

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

O que aprendemos

  • Como criar tarefas de destino HTTP.
  • Como criar tarefas de destino HTTP com a nova substituição de URI HTTP no nível da fila.
  • Como alterar as tarefas pendentes com a nova substituição de URI HTTP no nível da fila.
  • Como armazenar solicitações HTTP em buffer mais facilmente com a nova API BufferTask.