Gerencie o Tempo Limite de Visibilidade e a Nova Entrega

AWSBeginner
Pratique Agora

Introdução

Um consumidor recebe uma tarefa de pedido, mas para antes de confirmá-la. Você observará a mesma tarefa retornar, dará à próxima entrega mais tempo de processamento e verificará o pedido real antes da confirmação.

Conclua primeiro Envie e Consuma Tarefas com SQS. Esta VM independente fornece seu próprio consumidor, suas tabelas e seus dados de referência; filas, mensagens e identificadores de recebimento anteriores não são reutilizados.

Relação com as certificações

Certificação Tarefa do exame Prática
Solutions Architect – Associate (SAA-C03) Tarefa 2.1 Tempos de visibilidade SQS, reentrega e identificadores de recebimento.
Developer – Associate (DVA-C02) Tarefa 1.1 Tempos de visibilidade SQS, reentrega e identificadores de recebimento.
DevOps Engineer – Professional (DOP-C02) Tarefa 5.1 Prática dos fundamentos: Tempos de visibilidade SQS, reentrega e identificadores de recebimento.
Solutions Architect – Professional (SAP-C02) Tarefa 2.4 Prática dos fundamentos: Tempos de visibilidade SQS, reentrega e identificadores de recebimento.

Visão geral do laboratório

Diagrama conceitual: um trabalho SQS não confirmado volta a ficar disponível após o tempo de visibilidade e retorna com um novo receipt handle; processá-lo e verificar o pedido armazenado antes da confirmação.

Prepare uma Tarefa para Nova Entrega

Nesta etapa, crie uma fila com um tempo limite de visibilidade padrão curto e envie uma tarefa sem processá-la.

Use AWS View na parte superior para comparar as filas atuais, os resultados do consumidor e os pedidos armazenados. Preserve os dados de referência não relacionados.

Trabalhe no diretório de projeto preparado:

cd /home/labex/project

Crie uma fila Standard. Seu tempo limite de visibilidade padrão é de 30 segundos, usado quando uma solicitação de recebimento não especifica outro valor. $(...) salva o endereço selecionado da fila para comandos posteriores.

QUEUE_URL=$(aws sqs create-queue \
  --queue-name labex-q02-jobs \
  --attributes VisibilityTimeout=30 \
  --query QueueUrl \
  --output text)
echo "$QUEUE_URL"

Envie uma tarefa JSON:

aws sqs send-message \
  --queue-url "$QUEUE_URL" \
  --message-body '{"id":"redelivery-order","quantity":3}'

Leia o tempo limite padrão e as contagens:

aws sqs get-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attribute-names VisibilityTimeout ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible

Espere o tempo limite 30, uma mensagem disponível e zero mensagens em processamento. Em AWS View, a tarefa tem contagem de recebimentos zero, o Lambda fornecido não tem execução e não há pedido armazenado. O envio aceita a tarefa na fila; não a processa.

Observe a Expiração e uma Segunda Entrega

Nesta etapa, receba uma tarefa, deixe-a sem confirmação e observe uma segunda entrega após a expiração de sua visibilidade.

Uma mensagem, duas entregas

Após a expiração da visibilidade, a mesma mensagem pode ser entregue novamente com um novo identificador de recebimento.

O bloco de comandos a seguir é um único experimento cronometrado. Leia-o antes de executá-lo. O primeiro recebimento substitui a visibilidade por 10 segundos; o segundo recebimento imediato não deve encontrar nada enquanto a tarefa estiver oculta. sleep 12 espera que o prazo termine. O recebimento final dá à tarefa que retorna uma janela de 120 segundos para que você possa inspecioná-la sem correr contra o tempo limite curto. Cada > salva uma resposta JSON em um arquivo diferente.

aws sqs receive-message --queue-url "$QUEUE_URL" --max-number-of-messages 1 --visibility-timeout 10 --message-system-attribute-names ApproximateReceiveCount --output json > first-delivery.json
aws sqs receive-message --queue-url "$QUEUE_URL" --max-number-of-messages 1 --wait-time-seconds 0 --output json > while-hidden.json
sleep 12
aws sqs receive-message --queue-url "$QUEUE_URL" --max-number-of-messages 1 --visibility-timeout 120 --message-system-attribute-names ApproximateReceiveCount --output json > second-delivery.json

O recebimento vazio não processa nem exclui nada. Exiba essa resposta:

cat while-hidden.json

Espere uma resposta vazia, sem Messages. jq -s lê as duas respostas salvas juntas: .[0] é a primeira entrega e .[1] é a segunda. Compare a identidade da mensagem e o identificador de recebimento da entrega sem imprimir os identificadores:

jq -s '{
  same_message: (.[0].Messages[0].MessageId == .[1].Messages[0].MessageId),
  new_receipt: (.[0].Messages[0].ReceiptHandle != .[1].Messages[0].ReceiptHandle),
  receive_count: .[1].Messages[0].Attributes.ApproximateReceiveCount
}' first-delivery.json second-delivery.json

Espere que same_message e new_receipt sejam true, com contagem de recebimentos "2". Um ID de mensagem identifica a mensagem na fila entre as tentativas. Um identificador de recebimento identifica uma tentativa de entrega, portanto use sempre o identificador mais recente para alterar a visibilidade e excluir a mensagem.

AWS View mostra o mesmo corpo em processamento, recebido duas vezes, ainda sem pedido. Esta é uma nova entrega real após uma tentativa sem confirmação. Não foi necessário um segundo envio. Filas Standard também podem entregar duplicatas por outros motivos; o gerenciamento da visibilidade não fornece processamento exatamente uma vez.

Exemplo de AWS View: a mesma tarefa em processamento após a segunda entrega, ainda sem pedido armazenado; Este exemplo real mostra contagem de recebimentos dois antes do processamento de negócio. Os identificadores de mensagens diferem entre os ambientes de trabalho.

Amplie a Janela e Conclua o Trabalho

Nesta etapa, amplie a janela de processamento da entrega atual, conclua a execução do consumidor fornecido e confirme apenas após verificar os dados armazenados.

Escolha uma janela que permita concluir esta tentativa. Uma janela maior também atrasa a recuperação se o trabalhador parar. A visibilidade não bloqueia o registro do pedido: uma fila Standard pode repetir entregas mesmo enquanto a mensagem está oculta. Ampliar a janela e impedir efeitos de negócio duplicados resolvem problemas diferentes.

Selecione o identificador de recebimento mais recente na segunda resposta. jq -r escreve uma string simples adequada ao argumento do comando.

RECEIPT_HANDLE=$(jq -r '.Messages[0].ReceiptHandle' second-delivery.json)

Altere a visibilidade desta entrega específica para 300 segundos:

aws sqs change-message-visibility \
  --queue-url "$QUEUE_URL" \
  --receipt-handle "$RECEIPT_HANDLE" \
  --visibility-timeout 300

Esse novo intervalo começa quando a alteração é bem-sucedida. Ele mantém inalterada a configuração padrão de 30 segundos da fila e não confirma a tarefa. Se a janela de inspeção de 120 segundos já tiver expirado, receba a tarefa novamente em second-delivery.json e selecione seu identificador mais recente antes de alterar a visibilidade. Tentativas extras aumentam a contagem de recebimentos; use novamente o experimento cronometrado em um ambiente de trabalho novo se precisar repetir a observação exata de duas entregas.

Converta o corpo recebido de texto JSON em um objeto de tarefa:

jq '.Messages[0].Body | fromjson' second-delivery.json > job.json

Execute o Lambda fornecido e depois inspecione seu resultado:

aws lambda invoke \
  --function-name labex-q02-worker \
  --payload fileb://job.json worker-response.json
cat worker-response.json

Espere processed: true, quantidade 3 e total de 850 centavos. Leia o item persistido de forma independente:

aws dynamodb get-item \
  --table-name labex-q02-orders \
  --key '{"id":{"S":"redelivery-order"}}' \
  --consistent-read \
  --query Item

Somente após confirmar o resultado real armazenado, exclua usando o identificador de recebimento atual:

aws sqs delete-message --queue-url "$QUEUE_URL" --receipt-handle "$RECEIPT_HANDLE"
aws sqs get-queue-attributes \
  --queue-url "$QUEUE_URL" \
  --attribute-names VisibilityTimeout ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible

Espere o tempo limite padrão 30, zero mensagens disponíveis e zero em processamento. AWS View mostra uma fila vazia, a entrada e o resultado reais do consumidor e o pedido redelivery-order/3/850. A extensão da visibilidade reduziu a chance de outro consumidor receber a tarefa enquanto esta tentativa trabalhava. Ela não tornou a ação de negócio idempotente; unidades posteriores ensinam uma proteção durável contra efeitos duplicados.

Remova a Fila e o Resultado que Você Criou

Nesta etapa, remova sua fila, seu pedido e seus logs de execução, preservando os recursos de apoio fornecidos e os dados de referência.

aws sqs delete-queue --queue-url "$QUEUE_URL"
aws dynamodb delete-item \
  --table-name labex-q02-orders \
  --key '{"id":{"S":"redelivery-order"}}'
aws logs delete-log-group --log-group-name /aws/lambda/labex-q02-worker

Use consultas bem-sucedidas aos serviços para confirmar a ausência dos recursos e a disponibilidade da referência:

aws sqs list-queues
aws dynamodb scan --table-name labex-q02-orders --query Items
aws dynamodb scan --table-name labex-q02-reference --query Items

Nenhuma URL de fila ou item de pedido permanece. O item de referência ainda diz keep unchanged. AWS View mostra o mesmo estado de limpeza e o consumidor fornecido continua disponível. Erros de rede ou de autenticação não comprovam a exclusão.

Remova os arquivos locais de entrega e resposta:

rm -f first-delivery.json while-hidden.json second-delivery.json job.json worker-response.json

Execute a verificação da etapa antes de encerrar seu ambiente.

Resumo

Você observou uma tarefa SQS sem confirmação ficar disponível após a expiração da visibilidade, recebeu a mesma mensagem com um novo identificador de recebimento e uma contagem de recebimentos maior e ampliou o tempo de processamento da entrega atual. Você verificou um pedido real armazenado antes da confirmação e limpou sua fila, seu resultado e seus logs, preservando os recursos fornecidos.

Para aprofundar o tema, consulte a documentação da AWS: Tempo limite de visibilidade, nova entrega e alterações por mensagem.