Блог Amazon Web Services
Интеграция приложений с помощью очередей и сообщений
Оригинал статьи: ссылка (Mithun Mallick, Senior Solutions Architect, AWS)
В предыдущих постах этой серии, мы рассмотрели обмен сообщениями, а также основные критерии, которые стоит учитывать при выборе технологии транспортировки событий. В этом посте мы объясним основные принципы работы с сообщениями с помощью очередей, как их можно использовать при проектировании гибких систем, а также как вы можете применить их в своих задачах. AWS предлагает два сервиса по работе с очередями сообщений: Amazon Simple Queue Service (SQS) и Amazon MQ. В этом посте мы сосредоточимся на Amazon SQS.
Используемые сервисы
В современном цифровом мире даже самые простые архитектуры веб-приложений часто требуют очередей для интеграции между своими частями. Amazon SQS – это безопасный, надёжный и высокодоступный сервис очередей сообщений. Он предоставляет простой REST API интерфейс для создания очередей, а также для отправки, получения и удаления сообщений.
Отправка сообщений
Процессы, осуществляющие отправку сообщений, вызывают Amazon SQS API SendMessage. Amazon SQS поддерживает два типа очередей: стандартные и first-in-first-out (FIFO). Стандартные очереди не гарантируют порядок доставки сообщений (best effort ordering), в то время как FIFO доставляют сообщения в порядке отправки. Сообщения могут посылаться как по отдельности, так и пакетами из нескольких сообщений. Стандартные очереди поддерживают практически неограниченную пропускную способность при добавлении необходимого количества отправителей, тогда как FIFO-очереди поддерживают до 300 транзакций в секунду без пакетирования и до 3000 транзакций в секунду с пакетированием.
Что касается доставки сообщений, Amazon SQS поддерживает доставку по принципу «хотя бы один раз». Это значит, что каждое сообщение будет доставлено как минимум один раз, но иногда доставляется несколько копий одного сообщения. FIFO-очереди в Amazon SQS поддерживают строго однократную доставку, то есть отсутствие дубликатов сообщений.
Получение сообщений
Процессы, осуществляющие получение сообщений, вызывают Amazon SQS API ReceiveMessage. Сообщения из очередей могут обрабатываться как пакетами из нескольких сообщений, так и по одному за раз. У обоих подходов есть свои преимущества и недостатки.
- Обработка пакетами: каждое сообщение всё равно может обрабатываться независимо от других, то есть ошибка при работе с одним сообщением не приведет к проблеме со всем пакетом. Такой способ позволяет максимизировать пропускную способность обработки, а также предоставляет наибольшие возможности по оптимизации ресурсов, задействованных в получение сообщений.
- Обработка по отдельности: как правило, применяется в сценариях, когда каждое сообщение может приводить к запуску нескольких процессов на стороне получателя. В случае ошибки, повторение ограничивается отдельным сообщением.
Для соблюдения порядка обработки в случае FIFO-очередей, как правило, используется один процесс-получатель. При этом сообщения в разных группах внутри одной очереди могут обрабатываться параллельно, но общий лимит пропускной способности FIFO-очередей будет применяться в любом случае.
Amazon SQS поддерживает длинные (long polling) и короткие (short polling) запросы сообщений. При коротких запросах наличие сообщений проверяется только на части серверов Amazon SQS. В результате ответ будет или содержать найденные сообщения, или останется пустым при отсутствии сообщений на этих серверах – в любом случае, ответ вернется сразу после запроса. Длинный запрос проведёт опрос всех серверов и сразу вернет результат, если в очереди есть сообщения. При этом, если сообщений нет, длинный запрос может ожидать появления сообщения в очереди до 20 секунд. Таким образом, длинные запросы могут снизить затраты за счёт снижения количества API-вызовов от процесса-получателя к Amazon SQS при отсутствии сообщений (стоимость обоих видов запросов одинакова). Больше информации, а также пример исходного кода отправки и получения сообщений можно найти по ссылке.
Сам по себе запрос сообщений из очередей не представляет сложности, но при этом возникают накладные расходы из-за постоянного запуска процесса, который будет опрашивать очередь. В некоторых случаях может быть затруднительно его контролировать или искать причину возможной ошибки. Интеграция Amazon SQS с AWS Lambda позволит избежать этой трудоёмкой задачи благодаря переносу логики запроса сообщений в агент AWS Lambda.
Узнать больше об использовании Amazon SQS в качестве источника сообщений AWS Lambda можно в посте AWS Lambda Adds Amazon Simple Queue Service to Supported Event Sources. Такая возможность поддерживается и для стандартных, и для FIFO очередей.
Преимущества
Обработка сообщений с помощью очередей может защитить бэкенд-системы, такие как реляционные базы данных, от неожиданных всплесков трафика на фронтенде. Вы можете разделить логику обработки на части с использованием очереди между ними.
Например, рассмотрим сценарий, в котором web-приложение предоставляет возможность размещения заказов на товары, появившиеся в каком-то телесериале. В таком сценарии системы заказа и обработки платежей могут работать с традиционной реляционной базой данных. Во время популярных сезонов телесериалов очереди могут использоваться для контроля трафика к указанным системам. В диаграмме ниже мы показали, как запросы из web-приложения сохраняются в очередь, в то время как количество получателей сообщений в бэкенде зависит от производительности базы данных.
Обработка ошибок
Асинхронная обработка сообщений приводит к специфичной задаче по обработке ошибок: они просто накапливаются в виде записей в логе отправителя или получателя, при этом создавая отставание в обработке других сообщений. Чтобы решить эту проблему, в первую очередь необходимо понять причину ошибки. Если она является временной, имеет смысл повторить обработку сообщения после некоторой задержки, а в случае повторных ошибок переместить его в очередь необрабатываемых сообщений (dead letter queue, DLQ). Другой возможный сценарий –проблема в самих данных, которая не исчезнет после повторных попыток. Получатель должен это определить, и переместить сообщение в соответствующую очередь для ошибок.
В некоторых случаях стандартные очереди Amazon SQS могут осуществлять повторную доставку сообщения из-за своей распределённой архитектуры, что может привести к ошибкам, связанным с дублированием идентификаторов сообщений на стороне получателя. Лучший способ решения этой проблемы – создание идемпотентных обработчиков, которые возвращают одинаковый результат при повторной обработке одного и того же сообщения.
Заключение
В этом посте мы рассмотрели важность обмена сообщениями при проектировании распределённых приложений, отправку и получение сообщений с помощью очередей Amazon SQS, различие между FIFO и стандартными очередями, а также распространённые способы обработки ошибок. Кроме того, мы показали возможность использования Amazon SQS в качестве источника событий для AWS Lambda. Вы можете узнать больше информации об использовании сообщений в различных паттернах интеграций из следующих постов (англ.):
- Implementing enterprise integration patterns with AWS messaging services: point-to-point channels
- Implementing enterprise integration patterns with AWS messaging services: publish-subscribe channels
- Understanding asynchronous messaging for microservices
- Application integration patterns for microservices: Fan-out strategies