Введение
Службе исполнения заказов нужны все уведомления о заказах, а аналитике — только новые заказы. Вы опубликуете уведомление один раз для двух очередей, настроите разрешения доставки и отфильтруете уведомления аналитики.
Сначала выполните Отправку и потребление заданий с SQS и Защиту бакета ресурсной политикой. Эта независимая VM предоставляет настроенный CLI и несвязанные эталонные данные. Очереди служат получателями уведомлений; этой работе не нужен потребитель Lambda.
Связь с сертификацией
Эта лабораторная работа помогает на практике изучить следующие темы экзаменов.
- Cloud Practitioner (CLF-C02) · Задача 3.8: Рассылка SNS, фильтры подписок и разрешения доставки.
- Solutions Architect – Associate (SAA-C03) · Задача 2.1: Рассылка SNS, фильтры подписок и разрешения доставки.
- Developer – Associate (DVA-C02) · Задача 1.1: Рассылка SNS, фильтры подписок и разрешения доставки.
- DevOps Engineer – Professional (DOP-C02) · Задача 5.1: Базовая практика: Рассылка SNS, фильтры подписок и разрешения доставки.
- Solutions Architect – Professional (SAP-C02) · Задача 2.4: Базовая практика: Рассылка SNS, фильтры подписок и разрешения доставки.
Создание темы и разрешение доставки в очереди
На этом шаге создайте тему и две пустые очереди с разрешением доставки только из этой темы.
Amazon Simple Notification Service (SNS) распространяет одну публикацию через подписки темы. Используйте AWS View рядом с Terminal, чтобы сравнивать подключения темы, тела очередей и фильтры; сохраняйте эталонные данные.
cd /home/labex/project
Создайте тему SNS производителя. Подстановка команды $(...) сохраняет возвращённый ARN в переменной оболочки для следующих команд:
TOPIC_ARN=$(aws sns create-topic --name labex-q04-orders --query TopicArn --output text)
Создайте независимые места назначения и сохраните URL их очередей:
FULFILLMENT_URL=$(aws sqs create-queue --queue-name labex-q04-fulfillment --query QueueUrl --output text)
ANALYTICS_URL=$(aws sqs create-queue --queue-name labex-q04-analytics --query QueueUrl --output text)
Подписки используют ARN очередей как места назначения. Выберите оба идентификатора:
FULFILLMENT_ARN=$(aws sqs get-queue-attributes --queue-url "$FULFILLMENT_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
ANALYTICS_ARN=$(aws sqs get-queue-attributes --queue-url "$ANALYTICS_URL" --attribute-names QueueArn --query Attributes.QueueArn --output text)
Политика очереди предоставляет сервису SNS sqs:SendMessage для этой точной очереди с ограничением aws:SourceArn вашей темой. Одна конфигурация подписки не предоставляет разрешение доставки. Запишите по одной обычной политике JSON для каждой очереди; оболочка подставляет переменные ARN:
cat > fulfillment-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "sns.amazonaws.com"},
"Action": "sqs:SendMessage",
"Resource": "$FULFILLMENT_ARN",
"Condition": {"ArnEquals": {"aws:SourceArn": "$TOPIC_ARN"}}
}]
}
EOF
cat > analytics-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "sns.amazonaws.com"},
"Action": "sqs:SendMessage",
"Resource": "$ANALYTICS_ARN",
"Condition": {"ArnEquals": {"aws:SourceArn": "$TOPIC_ARN"}}
}]
}
EOF
Атрибут SQS Policy хранит строку JSON. --rawfile читает файл политики в эту строку, затем CLI применяет обычный файл атрибутов:
jq -n --rawfile policy fulfillment-policy.json '{Policy:$policy}' > fulfillment-attributes.json
jq -n --rawfile policy analytics-policy.json '{Policy:$policy}' > analytics-attributes.json
aws sqs set-queue-attributes --queue-url "$FULFILLMENT_URL" --attributes file://fulfillment-attributes.json
aws sqs set-queue-attributes --queue-url "$ANALYTICS_URL" --attributes file://analytics-attributes.json
Прочитайте настроенные разрешения:
aws sqs get-queue-attributes --queue-url "$FULFILLMENT_URL" --attribute-names QueueArn Policy
aws sqs get-queue-attributes --queue-url "$ANALYTICS_URL" --attribute-names QueueArn Policy
Обе политики указывают собственную очередь и одну и ту же тему заказов. AWS View показывает одну тему, две пустые очереди и пока ни одной подписки.
Подписка обеих очередей и фильтрация аналитики
На этом шаге подключите каждую очередь к теме и выберите, какие уведомления получает аналитика.

Подписка аналитики выбирает атрибут сообщения kind=created; каждая очередь получает собственную копию.
Подписка подключает протокол и конечную точку к теме SNS. Для sqs конечная точка — ARN очереди. Сохраните ARN подписок, чтобы настроить и позже удалить каждое подключение:
FULFILLMENT_SUB=$(aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$FULFILLMENT_ARN" --query SubscriptionArn --output text)
ANALYTICS_SUB=$(aws sns subscribe --topic-arn "$TOPIC_ARN" --protocol sqs --notification-endpoint "$ANALYTICS_ARN" --query SubscriptionArn --output text)
Политика фильтрации выбирает уведомления для одной подписки. Область фильтрации по умолчанию — атрибуты сообщения. Аналитика принимает только атрибут String kind со значением created; у службы исполнения заказов фильтра нет:
aws sns set-subscription-attributes --subscription-arn "$ANALYTICS_SUB" --attribute-name FilterPolicy --attribute-value '{"kind":["created"]}'
Проверьте обе подписки и атрибуты аналитики:
aws sns list-subscriptions-by-topic --topic-arn "$TOPIC_ARN"
aws sns get-subscription-attributes --subscription-arn "$ANALYTICS_SUB"
Ожидайте две конечные точки SQS и фильтр аналитики. Доставка исходного сообщения по умолчанию отключена, поэтому тела очередей будут содержать конверт уведомления SNS с темой, идентификатором сообщения, исходной строкой сообщения и атрибутами. Очереди остаются пустыми до публикации.
Подтверждение рассылки, фильтрации и границы доставки
На этом шаге опубликуйте два уведомления и проверьте реальные независимые доставки.
Опубликуйте событие создания. Сообщение JSON — бизнес-данные; отдельный атрибут String — то, что оценивает этот фильтр подписки:
aws sns publish --topic-arn "$TOPIC_ARN" --message '{"id":"fanout-order","kind":"created"}' --message-attributes '{"kind":{"DataType":"String","StringValue":"created"}}'
Опубликуйте событие обновления с тем же идентификатором заказа:
aws sns publish --topic-arn "$TOPIC_ARN" --message '{"id":"fanout-order","kind":"updated"}' --message-attributes '{"kind":{"DataType":"String","StringValue":"updated"}}'
Наблюдайте AWS View: служба исполнения заказов имеет два уведомления, аналитика — только уведомление создания. Проверьте счётчики:
aws sqs get-queue-attributes --queue-url "$FULFILLMENT_URL" --attribute-names ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible
aws sqs get-queue-attributes --queue-url "$ANALYTICS_URL" --attribute-names ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible
Получите сообщения для проверки с нулевой видимостью. Это немедленно освобождает синтетические сообщения для последующей очистки, не удерживая их в обработке. Пример доказывает независимые копии, а не обработку или подтверждение. fromjson читает каждую строку конверта, а конечный выбор полей показывает используемые здесь поля уведомления:
aws sqs receive-message \
--queue-url "$FULFILLMENT_URL" \
--max-number-of-messages 10 \
--visibility-timeout 0 \
--output json | jq '[.Messages[].Body | fromjson | {Type, TopicArn, MessageId, Message, MessageAttributes}]'
aws sqs receive-message \
--queue-url "$ANALYTICS_URL" \
--max-number-of-messages 10 \
--visibility-timeout 0 \
--output json | jq '[.Messages[].Body | fromjson | {Type, TopicArn, MessageId, Message, MessageAttributes}]'
Тело — конверт SNS: Type равен Notification, TopicArn — ваша тема, а Message содержит исходную строку JSON. Уведомление создания имеет один и тот же SNS MessageId в обеих очередях; каждая очередь хранит собственное сообщение SQS. Служба исполнения заказов также хранит событие обновления, которое аналитика отфильтровала. Независимые потребители могут подтверждать свои копии отдельно.
Теперь проверьте, почему разрешение темы имеет значение. Временно задайте aws:SourceArn службы исполнения заказов как ARN несвязанной синтетической темы:
jq --arg wrong 'arn:aws:sns:us-east-1:123456789012:labex-q04-unrelated' '.Statement[0].Condition.ArnEquals["aws:SourceArn"]=$wrong' fulfillment-policy.json > wrong-source-policy.json
jq -n --rawfile policy wrong-source-policy.json '{Policy:$policy}' > wrong-source-attributes.json
aws sqs set-queue-attributes --queue-url "$FULFILLMENT_URL" --attributes file://wrong-source-attributes.json
Опубликуйте уведомление обновления другого синтетического заказа. SNS принимает публикацию, но очередь исполнения заказов больше не авторизована для этой темы; аналитика фильтрует атрибут обновления:
aws sns publish --topic-arn "$TOPIC_ARN" --message '{"id":"blocked-order","kind":"updated"}' --message-attributes '{"kind":{"DataType":"String","StringValue":"updated"}}'
Убедитесь, что счётчики очередей остаются два и один, а конверта blocked-order в AWS View нет:
aws sqs get-queue-attributes --queue-url "$FULFILLMENT_URL" --attribute-names ApproximateNumberOfMessages
aws sqs get-queue-attributes --queue-url "$ANALYTICS_URL" --attribute-names ApproximateNumberOfMessages
Успешный ответ публикации доказывает принятие уведомления SNS; доставка в место назначения требует собственного подтверждения. Восстановите точную исходную политику перед проверкой шага:
aws sqs set-queue-attributes --queue-url "$FULFILLMENT_URL" --attributes file://fulfillment-attributes.json
Эта рабочая среда проверяет немедленную доставку в очереди одного аккаунта и фильтры атрибутов String. Изменения фильтров SNS в производственной среде могут распространяться до 15 минут, а неудачные доставки имеют поведение повторных попыток сервиса; этот короткий эксперимент разрешений не является моделью производственных повторных попыток.

Удаление подключений и временных уведомлений
На этом шаге удалите обе подписки, тему и очереди, сохранив несвязанные эталонные данные.
Сначала отмените подписку обеих конечных точек:
aws sns unsubscribe --subscription-arn "$FULFILLMENT_SUB"
aws sns unsubscribe --subscription-arn "$ANALYTICS_SUB"
Удалите тему и очереди. Удаление очередей отбрасывает синтетические уведомления; их бизнес-обработка не заявлялась:
aws sns delete-topic --topic-arn "$TOPIC_ARN"
aws sqs delete-queue --queue-url "$FULFILLMENT_URL"
aws sqs delete-queue --queue-url "$ANALYTICS_URL"
Докажите очистку успешными запросами непосредственно к сервисам:
aws sns list-topics
aws sns list-subscriptions
aws sqs list-queues
aws dynamodb scan --table-name labex-q04-reference --query Items
Списки тем и подписок пусты, URL очередей отсутствуют, а эталонная запись по-прежнему содержит keep unchanged. Ошибки аутентификации или сети не доказывают удаление. AWS View показывает те же пустые ресурсы.
Удалите свои обычные файлы конфигурации:
rm -f fulfillment-policy.json analytics-policy.json fulfillment-attributes.json analytics-attributes.json wrong-source-policy.json wrong-source-attributes.json
Выполните проверку очистки перед завершением среды.
Резюме
Вы подключили одну тему SNS к двум независимым очередям SQS, ограничили доставку точным источником темы и отфильтровали аналитику по атрибуту сообщения. Реальные конверты уведомлений подтвердили общее опубликованное событие и отдельные копии очередей. Вы также различили принятие публикации SNS и поступление доставки в её места назначения, затем удалили свои ресурсы, сохранив эталонные данные.
Потребителям очередей по-прежнему необходимо обрабатывать повторную доставку. Следующая работа применяет атомарное условие DynamoDB, чтобы повторные задания не создавали дублирующиеся бизнес-эффекты.



