Работа с тайм-аутом видимости и повторной доставкой

AWSBeginner
Практиковаться сейчас

Введение

Обработчик получает задание заказа, но останавливается до его подтверждения. Вы увидите возвращение того же задания, дадите следующей доставке больше времени на обработку и проверите реальный заказ перед подтверждением.

Сначала выполните Отправку и потребление заданий с SQS. Эта независимая VM предоставляет собственные обработчик, таблицы и эталонные данные; прежние очереди, сообщения и дескрипторы получения не используются.

Связь с сертификацией

Эта лабораторная работа помогает на практике изучить следующие темы экзаменов.

Подготовка задания к повторной доставке

На этом шаге создайте очередь с коротким тайм-аутом видимости по умолчанию и отправьте задание без его обработки.

Используйте AWS View рядом с Terminal, чтобы сравнивать текущие очереди, результаты обработчика и сохранённые заказы. Сохраните несвязанные эталонные данные.

Работайте в подготовленном каталоге проекта:

cd /home/labex/project

Создайте очередь Standard. Её тайм-аут видимости по умолчанию — 30 секунд; он используется, когда запрос получения не задаёт переопределение. $(...) сохраняет выбранный адрес очереди для последующих команд.

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

Отправьте одно задание JSON:

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

Прочитайте тайм-аут по умолчанию и счётчики:

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

Ожидайте тайм-аут 30, одно доступное сообщение и ноль сообщений в обработке. В AWS View число получений задания равно нулю, предоставленная Lambda не имеет выполнения и сохранённого заказа нет. Отправка принимает задание в очередь; она не обрабатывает его.

Наблюдение истечения видимости и второй доставки

На этом шаге получите задание, оставьте его неподтверждённым и увидите вторую доставку после истечения его видимости.

Одно сообщение, две доставки

После истечения видимости то же сообщение может быть доставлено снова с новым дескриптором получения.

Следующий блок команд — один эксперимент с заданным временем. Прочитайте его перед запуском. Первое получение переопределяет видимость на 10 секунд; немедленное второе получение не должно ничего найти, пока задание скрыто. sleep 12 ждёт истечения срока. Последнее получение даёт возвращённому заданию окно 120 секунд, чтобы вы могли проверить его без гонки с коротким тайм-аутом. Каждый > сохраняет ответ JSON в отдельный файл.

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

Пустое получение ничего не обрабатывает и не удаляет. Покажите этот ответ:

cat while-hidden.json

Ожидайте пустой ответ без Messages. jq -s читает два сохранённых ответа вместе: .[0] — первая доставка, а .[1] — вторая. Сравните идентификацию сообщения и дескриптор доставки, не выводя сами дескрипторы:

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

Ожидайте same_message и new_receipt равными true с числом получений "2". Идентификатор сообщения определяет сообщение очереди между попытками. Дескриптор получения определяет одну попытку доставки, поэтому всегда используйте самый последний дескриптор для изменения видимости и удаления.

AWS View показывает то же тело в обработке, полученное дважды, пока без заказа. Это реальная повторная доставка после неподтверждённой попытки. Вторая отправка не потребовалась. Очереди Standard могут доставлять дубликаты и по другим причинам; управление видимостью не обеспечивает обработку ровно один раз.

Пример AWS View: то же задание находится в обработке после второй доставки, пока без сохранённого заказа

Этот действительный пример показывает число получений два до бизнес-обработки. Идентификаторы сообщений отличаются между рабочими средами.

Продление окна и завершение работы

На этом шаге продлите окно обработки текущей доставки, выполните предоставленный обработчик и подтвердите сообщение только после проверки сохранённых данных.

Выберите самый последний дескриптор получения из второго ответа. jq -r записывает обычную строку, подходящую для аргумента команды.

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

Измените видимость этой конкретной доставки на 300 секунд:

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

Новый интервал начинается после успешного изменения. Он сохраняет настройку очереди по умолчанию 30 секунд и не подтверждает задание. Если окно проверки 120 секунд уже истекло, получите задание снова в second-delivery.json и выберите его самый последний дескриптор перед изменением видимости. Дополнительные попытки увеличивают число получений; повторите эксперимент с заданным временем в новой рабочей среде, если нужно повторить наблюдение ровно двух доставок.

Преобразуйте полученное тело из текста JSON в объект задания:

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

Запустите предоставленную Lambda, затем проверьте её результат:

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

Ожидайте processed: true, количество 3 и сумму 850 центов. Независимо прочитайте сохранённую запись:

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

Только после подтверждения действительного сохранённого результата удалите сообщение с текущим дескриптором получения:

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

Ожидайте тайм-аут по умолчанию 30, ноль доступных и ноль обрабатываемых сообщений. AWS View показывает пустую очередь, реальные входные данные и результат обработчика и заказ redelivery-order/3/850. Продление видимости уменьшило вероятность получения задания другим обработчиком во время работы этой попытки. Оно не сделало бизнес-действие идемпотентным; последующие работы обучают устойчивой защите от повторных эффектов.

Удаление очереди и результата упражнения

На этом шаге удалите свою очередь, заказ и журналы выполнения, сохранив предоставленные ресурсы и эталонные данные.

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

Используйте успешные запросы сервисов для подтверждения отсутствия ресурсов и доступности эталона:

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

URL очередей и записи заказов не остаются. Эталонная запись по-прежнему содержит keep unchanged. AWS View показывает то же состояние очистки, а предоставленный обработчик остаётся доступным. Ошибки сети или аутентификации не могут доказать удаление.

Удалите локальные файлы доставок и ответов:

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

Выполните проверку шага перед завершением своей среды.

Резюме

Вы увидели, как неподтверждённое задание SQS стало доступным после истечения видимости, получили то же сообщение с новым дескриптором получения и увеличенным числом получений и продлили время обработки текущей доставки. Вы проверили реальный сохранённый заказ перед подтверждением и очистили свою очередь, результат и журналы, сохранив предоставленные ресурсы.