
Автор статьи: Рустем Галиев
IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM
Привет, Хабр!
Поговорим про SNS.
Amazon Simple Notification Service (AWS SNS) — это мощный инструмент в арсенале облачных сервисов Amazon Web Services, предоставляющий простые и эффективные средства для управления уведомлениями и распределения сообщений в распределенных системах. SNS обеспечивает высокую гибкость в организации коммуникации между различными компонентами приложений, позволяя быстро и эффективно реагировать на разнообразные события и изменения в окружающей среде. В данной статье мы рассмотрим ключевые особенности и возможности AWS SNS, а также проанализируем, как этот сервис способствует созданию устойчивых и масштабируемых архитектур облачных приложений.
Amazon Simple Notification Service (AWS SNS) – технологическое воплощение эффективного управления уведомлениями в облачных приложениях. Этот сервис Amazon Web Services стал неотъемлемой частью инфраструктуры многих успешных проектов, предоставляя разработчикам инструмент для быстрой, надежной и гибкой организации коммуникаций в распределенных системах.
Одним из ключевых применений AWS SNS является облачная архитектура, где этот сервис служит эффективным мостом между микросервисами. Обеспечивая мгновенную реакцию на события и уведомляя компоненты системы о происходящих изменениях, SNS упрощает взаимодействие между частями приложения и повышает его устойчивость.
В мобильной разработке AWS SNS занимает центральное место, предоставляя средства для отправки уведомлений на мобильные устройства через различные каналы, включая пуш-уведомления. Это существенно улучшает взаимодействие с пользователями мобильных приложений, повышая их вовлеченность.
В области мониторинга и логирования AWS SNS служит надежным инструментом для оперативного оповещения о возможных проблемах. Мгновенные уведомления об изменениях в статусе приложения или обнаруженных аномалиях позволяют оперативно реагировать и обеспечивают высокую доступность системы.
Но AWS SNS – это не только внутренний инструмент для облачных проектов. Сервис успешно интегрируется с другими сервисами AWS и внешними платформами, обеспечивая эффективное взаимодействие между различными системами.
Я бы хотел начать этот цикл статей с Dead Letter Queues (DLQs).
Dead Letter Queues (DLQs) — это механизм, используемый в системах обработки сообщений и предназначенный для обработки сообщений, которые не удалось успешно доставить конечной точке (consumer) после нескольких попыток. В случае, когда сообщение не может быть успешно обработано и доставлено своему адресату, оно направляется в Dead Letter Queue для дальнейшего анализа и обработки.
Основная цель Dead Letter Queues состоит в том, чтобы предоставить механизм для обработки сообщений, которые, по различным причинам, не могут быть успешно обработаны основной системой. Это может произойти, например, из-за ошибок в формате сообщения, превышения времени жизни сообщения, или если конечная точка (consumer) не может обработать сообщение по какой-то другой причине.
Нам потребуется создать новую тему для демонстрации механизма очереди мертвых писем (DLQ). Для создания новой темы можно использовать команду create-topic SNS
.
Как показано ниже, команда create-topic
создаст тему с именем my-standard-topic;
она выводит ARN ресурса в консоль, который мы сохраним в локальной переменной с именем TOPIC_ARN
:
TOPIC_ARN=`aws sns create-topic \
--name my-standard-topic \
--output text \
--query TopicArn`
echo "Standard topic with ARN $TOPIC_ARN created successfully"

Исполнение вышеуказанной команды создаст стандартную тему. ARN темы, отправленный в ответе, затем разбирается и сохраняется в переменную TOPIC_ARN
.
Мы можем использовать метод create-queue
в сервисе SQS для создания очереди:
QUEUE_URL=`aws sqs create-queue \
--queue-name my-standard-queue \
--output text \
--query 'QueueUrl'`
echo "Queue URL is $QUEUE_URL"
Исполнение этой команды создаст очередь с именем my-standard-queue
. Команда create-queue
выведет URL очереди, который в данном случае будет сохранен в локальной переменной (QUEUE_URL
).
ARN очереди требуется при установке политики на очередь, а также при подписке на тему. Мы можем получить его, используя метод get-queue-attributes
в сервисе SQS:
QUEUE_ARN=`aws sqs get-queue-attributes \
--queue-url $QUEUE_URL \
--attribute-names QueueArn \
--query 'Attributes.QueueArn' \
--output text`
echo "Queue ARN is $QUEUE_ARN"
Исполнение этой команды извлекает ARN очереди и сохраняет его в локальной переменной (QUEUE_ARN
).
Поскольку тема и очередь готовы, следующим шагом является создание подписки на тему. В данном случае конечной точкой подписки будет служить SQS-очередь.
Следующая команда создает подписку SQS на тему:
export AWS_PAGER=""
aws sns subscribe \
--topic-arn $TOPIC_ARN \
--protocol sqs \
--notification-endpoint $QUEUE_ARN
Исполнение этой команды подписывает нашу очередь на указанную тему.
Для публикации всех непрошедших сообщений нам потребуется DLQ. Процесс создания точно такой же, как и при создании стандартной очереди:
DLQ_QUEUE_URL=`aws sqs create-queue \
--queue-name my-dlq-queue \
--output text \
--query 'QueueUrl'`
echo "DLQ queue's URL is $DLQ_QUEUE_URL"
Затем нам нужно получить ARN DLQ:
DLQ_QUEUE_ARN=`aws sqs get-queue-attributes \
--queue-url $DLQ_QUEUE_URL \
--attribute-names QueueArn \
--query 'Attributes.QueueArn' \
--output text`
echo "DLQ queue ARN is $DLQ_QUEUE_ARN"
Нам нужно настроить политику перенаправления (redrive policy) для настройки очереди DLQ для основной SQS-очереди. Следующий фрагмент кода выполняет это:
# Setting the DLQ redrive policy
aws sqs set-queue-attributes \
--queue-url $QUEUE_URL \
--attributes '{"RedrivePolicy": "{\"maxReceiveCount\":\"3\", \"deadLetterTargetArn\":\"'"$DLQ_QUEUE_ARN"'\"}"}'
Исполнение этой команды настраивает DLQ для основной SQS-очереди. Сообщения, которые не могут быть обработаны более трех раз, будут направляться в DLQ, согласно настроенной на очереди политике перенаправления (RedrivePolicy).
Поскольку от сервиса SNS ожидается публикация сообщений в нашу очередь, нам нужно установить соответствующие разрешения на очередь. Для этого мы прикрепим политику к очереди.
Также нам нужен файл политики queue-policy-template.json, который состоит из строковой версии JSON-документа.
{
"Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},\"Action\":\"sqs:SendMessage\",\"Resource\":\"arn:aws:sqs:us-east-1:ACCOUNT_ID:my-standard-queue\",\"Condition\":{\"ArnLike\":{\"aws:SourceArn\":\"arn:aws:sns:us-east-1:ACCOUNT_ID:my-standard-topic\"}}}]}"
}
Всё, что нам нужно сделать, это убедиться, что шаблонная версия заменена на соответствующие значения, что выполняется следующей командой sed
на файле шаблона:
value in the policy file
sed "s=ACCOUNT_ID=$AWS_ACCOUNT_ID=g" queue-policy-template.json > queue-policy.json
Исполнение этого кода создает конечную политику с фактическим значением вместо переменной. Ожидается, что мы прикрепим конечный файл политики к нашей очереди.
Теперь устанавливаем эту политику на очередь, чтобы разрешить попыткам SNS публиковать сообщения. Это выполняется путем вызова метода set-queue-attributes
в сервисе SQS:
aws sqs set-queue-attributes \
--queue-url $QUEUE_URL \
--attributes file://queue-policy.json
Мы отправим тестовое сообщение в тему (представленную ARN темы), вызвав метод publish:
aws sns publish \
--topic-arn $TOPIC_ARN \
--message "This is Message A"
Мы отправим тестовое сообщение в тему (представленную ARN темы), вызвав метод publish
:
aws sns publish \
--topic-arn $TOPIC_ARN \
--message "This is Message A"
Исполнение вышеуказанного фрагмента кода опубликует сообщение в стандартную тему.
Представим, что у нашей основной SQS-очереди возникла ошибка обработки, и она не может обработать сообщение. Для моделирования этого сценария мы получим сообщение, но не будем его удалять: фактически потребляем его, но не обрабатываем.
Примечание: В реальных приложениях мы обычно удаляем сообщение после успешной обработки из очереди SQS. Если вы не удаляете сообщение явным образом, сообщение снова становится видимым в очереди после истечения периода видимости. Это может привести к потенциальной обработке дубликатов.
Напомним, что мы установили максимальное количество повторных попыток (maxReceiveCount) в 3. Теперь мы попытаемся получить сообщение более 5 раз, отправляя его в DLQ:
for i in {1..5};
do
echo "Receiving the message"
aws sqs receive-message \
--queue-url $QUEUE_URL
done

Исполнение этой команды попытается получить сообщения из очереди 5 раз. Однако, поскольку максимальное количество повторных попыток превышает количество попыток извлечения, сообщение не будет обработано. Вместо этого неудачное сообщение появится в очереди DLQ. Мы можем проверить эти сообщения, появившиеся в очереди DLQ.
Непрошедшие сообщения из основной очереди отправляются в DLQ. Так же, как мы получали сообщения из стандартной очереди с помощью команды receive-message
, мы будем использовать ту же команду для получения сообщений из DLQ.
Следующая команда демонстрирует извлечение сообщений из DLQ:
aws sqs receive-message \
--queue-url $DLQ_QUEUE_URL
Исполнение этой команды извлечет сообщения, которые были отправлены в DLQ.
Иногда вы можете не получить сообщений из DLQ. Из-за распределенной архитектуры мессенджинга могут возникнуть задержки в передаче сообщений в DLQ. Мой совет — повторить вышеуказанную команду несколько раз. Мы также можем войти в консоль AWS и проверить наличие сообщений об ошибках в очереди DLQ.
Это демонстрирует функциональность DLQ: сообщения, которые не были обработаны потребителем в основной очереди, направляются в очередь мертвых писем для повторной обработки или для целей регистрации/аудита.
В завершение напоминаю про открытый урок, который пройдет 14 марта в 20:00 в рамках курса "Cloud Solution Architecture". Тема — «Безопасность в процессе создания облачного ПО в Yandex.Cloud». Этот урок будет полезен всем, кто интересуется созданием облачных решений и хочет лучше понять, как обеспечить безопасность на каждом этапе разработки. Записаться можно по ссылке.