Блог Amazon Web Services
Построение отказоустойчивых бессерверных паттернов путём комбинации сервисов сообщений
Оригинал статьи: ссылка (James Beswick, Senior Developer Advocate, AWS Serverless Team) часть 1, часть 2 (текущая), часть 3
В блоге “Выбор сервисов сообщений для бессерверных приложений” я рассказал о функционале и отличиях между основными сервисами сообщений в AWS. Amazon SQS, Amazon SNS и Amazon EventBridge предоставляют функционал очередей, модели «издатель-подписчик» и шины сообщений для ваших приложений. По отдельности каждый из этих сервисов – надёжный и масштабируемый, что делает их ключевыми сервисами для построения бессерверных архитектур.
Однако вы также можете комбинировать эти сервисы для решения некоторых проблем в распределённых архитектурах. Используя специфичный функционал каждого сервиса, можно создавать довольно продвинутые архитектурные паттерны при минимальном объёме кода. Такие комбинации могут сделать ваши приложения более отказоустойчивыми, масштабируемыми и помогут снизить объём дополнительной логики и архитектурной сложности в ваших рабочих нагрузках.
В этом посте я расскажу о некоторых важных паттернах для разработчиков бессерверных приложений и покажу, как можно развернуть такие сервисные интеграции с помощью AWS Serverless Application Model (AWS SAM).
Примеры кода, используемые в данной статье, вы сможете найти и загрузить из репозитория GitHub. Файл README.md содержит инструкции по запуску и развёртыванию каждого из примеров кода.
SNS вместе с SQS: добавление отказоустойчивости и регулирование пропускной способности сообщений
SNS предоставляет надёжную политику повторной отправки сообщений, которая позволяет осуществить до 100 010 попыток отправки на протяжении 23 дней. Если конечный адресат недоступен, он может быть перегружен повторениями, когда снова заработает. Вы можете решить данную проблему добавлением очереди SQS.
Добавление очереди SQS между SNS-топиком и подписчиком имеет следующие преимущества. Во-первых, это добавляет отказоустойчивости при доставке сообщения, так как оно гарантированно сохраняется в очереди. Во-вторых, это ограничивает количество сообщений, отправляемых подписчику, помогая сгладить всплески трафика, вызванные попыткой сервиса до-отправить пропущенные сообщения.
Чтобы реализовать такой подход с помощью шаблона AWS SAM, нужно определить два ресурса и SNS-подписку:
MySqsQueue:
Type: AWS::SQS::Queue
MySnsTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Protocol: sqs
Endpoint: !GetAtt MySqsQueue.Arn
И, наконец, предоставить права доступа SNS-топику на публикацию сообщений в очередь с помощью ресурса AWS::SQS::QueuePolicy:
SnsToSqsPolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: "Allow SNS publish to SQS"
Effect: Allow
Principal: "*"
Resource: !GetAtt MySqsQueue.Arn
Action: SQS:SendMessage
Condition:
ArnEquals:
aws:SourceArn: !Ref MySnsTopic
Queues:
- Ref: MySqsQueue
Чтобы протестировать получившееся решение, можно отправить сообщение в SNS-топик и проверить длину очереди SQS с помощью AWS CLI:
aws sns publish --topic-arn "arn:aws:sns:us-east-1:123456789012:sns-sqs-MySnsTopic-ABC123ABC" --message "Test message"
aws sqs get-queue-attributes --queue-url "https://sqs.us-east-1.amazonaws.com/123456789012/sns-sqs-MySqsQueue- ABC123ABC " --attribute-names ApproximateNumberOfMessages
Вы должны получить результат, подобный представленному ниже:
Другой вариант использования данного паттерна – это фильтрация сообщений в очереди SQS. Расположив SNS-топик перед очередью, вы можете использовать функционал фильтрации сообщений сервиса SNS. Это гарантирует, что только нужные вам сообщения попадут в очередь. Для использования фильтрации сообщений в AWS SAM используйте ресурс AWS:SNS:Subcription:
QueueSubcription:
Type: 'AWS::SNS::Subscription'
Properties:
TopicArn: !Ref MySnsTopic
Endpoint: !GetAtt MySqsQueue.Arn
Protocol: sqs
FilterPolicy:
type:
- orders
- payments
RawMessageDelivery: 'true'
EventBridge вместе с SNS: комбинация функционала обоих сервисов
Оба сервиса, SNS и EventBridge, имеют разный набор поддерживаемых адресатов и интеграций. Таблица сравнивает основные различия между двумя сервисами:
Amazon SNS | Amazon EventBridge | |
Количество адресатов | 10 млн (можно изменить) | 5 |
Ограничения | 100 тыс. топиков. 12,5 млн подписок на топик. |
100 шин сообщений. 300 правил на шину сообщений. |
Преобразование входящих сообщений | Нет | Да – см. детали. |
Фильтрация сообщений | Да – см. детали. | Да, включая IP адреса – см. детали. |
Поддерживаемые форматы | Raw или JSON | JSON |
Получение сообщений из AWS CloudTrail | Нет | Да |
Адресаты | HTTP(S), SMS, SNS Mobile Push, Email/Email-JSON, SQS, Lambda-функции | 15 адресатов, включая: AWS Lambda, Amazon SQS, Amazon SNS, AWS Step Functions, Amazon Kinesis Data Streams, Amazon Kinesis Data Firehose. |
Интеграция с SaaS-провайдерами | Нет | Да – см. список партнёров. |
Интеграция c Schema Registry | Нет | Да – см. детали. |
Поддержка Dead-letter очередей | Да | Нет |
Публичная доступность | Можно создавать публичные топики | Нет |
Межрегиональное взаимодействие | Функция AWS Lambda может подписаться на SNS-топик в любом регионе. | Адресаты должны быть в одном регионе. Можно отправлять сообщения между регионами в другие шины сообщений. |
В этом паттерне вы настраиваете SNS-топик в качестве адресата для правила EventBridge:
В шаблоне AWS SAM вы определяете указанные выше ресурсы следующим образом:
Resources:
MySnsTopic:
Type: AWS::SNS::Topic
EventRule:
Type: AWS::Events::Rule
Properties:
Description: "EventRule"
EventPattern:
account:
- !Sub '${AWS::AccountId}'
source:
- "demo.cli"
Targets:
- Arn: !Ref MySnsTopic
Id: "SNStopic"
EventBridge-шина «по умолчанию» уже существует в каждом аккаунте AWS, поэтому её определять не нужно. Для публикации событий, соответствующих заданным правилам, из EventBridge в SNS-топик нужно определить права доступа, используя ресурс AWS::SNS::TopicPolicy:
EventBridgeToToSnsPolicy:
Type: AWS::SNS::TopicPolicy
Properties:
PolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sns:Publish
Resource: !Ref MySnsTopic
Topics:
- !Ref MySnsTopic
EventBridge имеет ограничение на пять адресатов на правило. В случаях, когда необходимо отправить сообщение сотням или тысячам адресатов, публикация сообщений в SNS топик и затем подписка адресатов на этот топик помогает обойти указанное ограничение EventBridge. Оба сервиса поддерживают разных адресатов, и данный паттерн помогает доставлять сообщения из EventBridge на следующие каналы: SMS, HTTP(s), email и мобильные уведомления SNS.
Можно преобразовывать и фильтровать сообщения, используя эти сервисы, часто даже без необоходимости использования функций AWS Lambda. SNS не поддерживает преобразование входящих сообщений, но вы можете это сделать в правиле EventBridge. Фильтрация сообщений поддерживается обоими сервисами, но EventBridge предоставляет больше возможностей.
AWS CloudTrail может логировать и мониторить события, происходящие в сервисах AWS. Он может быть полезным источником событий, позволяя реагировать, например, на изменения объектов в Amazon S3 или изменения в вашей среде разработки. Такой подход натурально интегрируется с EventBridge, позволяя доставлять сообщения от десятков сервисов.
EventBridge также позволяет интегрироваться с источниками событий за пределами вашего аккаунта AWS, предлагая интеграции с SaaS-провайдерами, такими как Zendesk, PagerDuty и Auth0. Сообщения доставляются в партнёрскую шину сообщений в вашем аккаунте и затем могут быть отфильтрованы и направлены в SNS-топик для обработки.
Помимо этого, данный паттерн позволяет доставлять сообщения в Lambda-функции в других аккаунтах AWS и в другие регионы. Вы можете запускать Lambda на базе сообщений из SNS-топиков в других регионах и аккаунтах AWS. Вы также можете сделать SNS-топик публичным и открытым только на чтение, предоставляя точку интеграции и расширения для сторонних провайдеров и подписчиков. SNS предоставляет расширенные возможности контроля доступа, которые вы можете интегрировать в данный паттерн.
EventBridge вместе с SQS: построение отказоустойчивых микросервисов
EventBridge может перенаправлять сообщения различным адресатам, включая микросервисы. В случае каскадных ошибок в пайплайне обработки сервис будет повторять отправку сообщений на протяжении 24 часов. Для приложений, требующих более долгий период хранения, можно отправлять сообщения в SQS-очередь, созданную для каждого из микросервисов. Это позволит гарантированно сохранить сообщения до момента полного восстановления микросервиса, подписанного на данную очередь. В дополнение, данный паттерн защищает микросервисы от всплесков трафика путём ограничения количества обрабатываемых за раз сообщений.
Ресурсы в шаблоне AWS SAM похожи на предыдущие примеры, но используют ресурс AWS::SQS::QueuePolicy для предоставления прав доступа к EventBridge:
EventBridgeToToSqsPolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: SQS:SendMessage
Resource: !GetAtt MySqsQueue.Arn
Queues:
- Ref: MySqsQueue
Выводы
Вы можете комбинировать сервисы сообщений в ваших архитектурах для реализации сложных паттернов, минимизируя затраты на написание дополнительного кода. Данный пост показывает три примера, демонстрирующих подходы для ограничения всплесков трафика и сохранения сообщений в очереди для последующей обработки, интеграции SNS и EventBridge, а также построения отказоустойчивых микросервисных архитектур.
Чтобы узнать больше о разделённых (decoupled) архитектурах, смотрите серию обучающих матералов по EventBridge. Чтобы ознакомиться с обучающими материалами по бессерверным технологиям, смотрите https://serverlessland.com.