Очередь сообщений (Message Queue, MQ): что это такое и как влияет на рекрутинг

Сейчас среди требований по многим бэкенд-вакансиям можно увидеть термины RabbitMQ, ActiveMQ, Kafka. Это названия очередей сообщений (Message Queue). Обычно такое требование в вакансии усложняет поиск: нужно обращать больше внимания на опыт кандидатов, фильтруя их резюме. Иногда и без того небольшой рынок специалистов становится еще меньше, так как рекрутер должен отсечь кандидатов по дополнительному навыку.
MQ — что это, зачем нужны очереди сообщений и почему рекрутерам нужно обращать внимание на подобное требование — рассказываю далее в статье.
Что такое очередь сообщений и message broker простыми словами
Очередь сообщений — это механизм для асинхронного обмена сообщениями между компонентами системы. Если упростить, это про способ организации данных. Если у вас накапливается множество разных данных и запросов, в них сложно разобраться. Разные подходы к таким данным можно сравнить со стопкой бумаг: вы можете накинуть все в кучу или сложить аккуратной стопкой, чтобы было удобно разобрать в опредленном порядке. Последний вариант и является визуализацией очереди сообщений.
В тоже время в понятие MQ включают и кеш сообщений. Из-за такой двойственности разработчики используют также NoSQL базу данных Redis (подходит для примитивных задач кеширования). Именно поэтому рекрутеры на вопрос про опыт с Message Queue могут получить ответ «использовал Redis». Однако это только базовый уровень работы с очередями, поэтому не спешите передавать кандидата менеджеру.
Для более продвинутой работы используют специальную программу — message broker. Она помогает распределять сообщения по группам и разным получателям. Таким образом, можно разделить работу по чтению сообщений среди нескольких исполнителей. Чаще всего на вакансиях с требованием в очередях сообщений имеют в виду именно брокеры.
Большинство очередей носят названия с окончанием “MQ”, что значит, что перед вами разработчик с опытом в очередях сообщений. К примеру, вы могли встретить RabbitMQ, ActiveMQ, MSMQ. Единственные исключения составляют Kafka и SQS.
Как работает очередь сообщений
Если вам попался разработчик без опыта с очередями сообщений, то он вероятно работал либо только над небольшими проектами, либо над доисторическими проектами-монолитами (чем-то средним между пирамидой Хеопса и гигантским общежитием). Такую архитектуру проще использовать, она хорошо годится для небольших, особенно учебных, pet-проектов. Оптимальна для небольших команд.
Но у нее есть и минусы: она не подходит для масштабирования и больших нагрузок. Для решения этих проблем и придумали очереди сообщений.
Вот как они работают на практике. Представьте классический почтовый сервис (к примеру, Новую почту). Если вы куда-то переезжаете, вы должны сообщить своим друзьям новый почтовый индекс. Это позволит вам получать письма с разных локаций и отделений. Сама почта при этом обрабатывает миллионы писем и адресов. Она точно знает, кому эти письма доставлять, несмотря на то, что кто-то получает их раз в день, а кто-то — раз в месяц.
Так и работают и очереди сообщений. Это отдельный сервис, который «подписывает» исполнителей/получателей на отдельный тип запросов. При этом отправитель может указать получателем человека в любой локации, не имея прямой связи с ним. Это позволяет создать универсальную структуру, где достаточно доступа к очередям и «адресам» для обмена данными.
Само название содержит слово «очередь» именно потому, что она помогает формировать последовательность к обработке запросов: не нужно обрабатывать их все одновременно или ждать, когда вы закончите читать одно «письмо», прежде чем начать другое — даже при большой загрузке ничего не потеряется и система будет работать верно.
Смотреть детальнее
Распределенная архитектура
Messagequeue часто употребляются с понятием распределенной архитектуры. В таком решении компоненты программы находятся на разных платформах. Они могут взаимодействовать друг с другом по сети связи для достижения определенной цели.
На практике это помогает IT-компаниям донанимать сотрудников в распределенную команду из разных уголков мира или даже аутстаффить отдельные фичи/подпроекты для разработки одного продукта.
Свяжитесь с нами уже сейчас
Заказать консультацию
Микросервисная архитектура
Частный случай описанной системы — это микросервисная архитектура (microservices). Микросервисы также часто идут рука об руку с очередями сообщений.
Когда сервер состоит не из одной программы, а из десятка мини-программ, которые общаются друг с другом и пользователями, это называют микросервисной архитектурой (microservices). Каждый микросервис должен быть максимально компактным и отвечать за узкий спектр задач, объединенных одной тематикой. В идеале — один микросервис на одну задачу. Отдельные микросервисы можно отключать, заменять и обновлять на более новые — это не должно мешать работе программы в целом. Однако такой подход значительно усложняет архитектуру сервера и требует более высокой квалификации разработчиков (а значит и больше издержек на зарплатный фонд).
Если на примере, то наш почтовый сервис сможет передавать данные и на другие континенты, так как система почтовых адресов универсальна. Также и с программами: разные части продукта могут соединяться друг с другом из разных уголков мира, а к их разработке можно подключить большие команды без ущерба процессам.

Смотреть детальнее
Очередь сообщений: преимущества и недостатки системы
Эта универсальная система построила современный подход архитектуры приложений: их можно масштабировать, легко заменять отдельные части без ущебра для работы продукта. Если подсуммировать, преимущества использования очереди сообщений следующие:
- автономность процессов и асинхронность,
- распределенность,
- масштабируемость,
- эффективное использование ресурсов,
- приспособленность к многопоточности,
- адаптивность к высокой нагрузке,
- гарантированная доставка и порядок доставки и так далее.
Среди минусов: удорожание и усложнение архитектуры проекта. Такой подход требует больше ресурсов на разработку и более высоких навыков команды, чтобы реализовать нужные решения.
Как Message Queue влияет на рекрутинг в IT
MQ — это верный признак продукта, над которым работает множество команд и который нацелен на большую аудиторию. Что значит mq в резюме кандидатов? Обычно они указывают на опытного программиста, который не понаслышке знаком с серьезной разработкой.
При этом никто не запрещает юзать очередь сообщений для солидности: иногда она как пятое колесо, зато круто выглядит в резюме. Так что будьте внимательны и рассматривайте CV комплексно.
С другой стороны, и hiring менеджеры могут завышать требования, добавляя Message Queue в описание вакансии на всякий случай, на перспективу. Конечно, такое требование сужает рынок доступных кандидатов и растягивает time-to-hire. Поэтому вникайте в описание проекта, сопоставляйте его с вашей вакансией и переспрашивайте менеджера/клиента о том, какие скиллы — must-have, а какие можно упустить.
Что такое очередь сообщений?
Очередь сообщений — это механизм для асинхронного обмена сообщениями между компонентами системы. Обычно Message Queue — маркер серьезного продукта, над которым работает множество команд и который нацелен на большую аудиторию.
Как работает очередь сообщений?
MQ помогает грамотно выстроить очередь запросов для обработки. Все сообщения обрабатываются определенной частью программы, гарантируется их доставка, порядок доставки и хранение. При этом разные части программы работают над запросами автономно, что уберегает от сбоев в работе всей системы.
Какие бывают очереди сообщений?
Большинство очередей носят названия с околнчанием “MQ”, по которой их легко узнать: RabbitMQ, ActiveMQ, MSMQ. Исключения составляют Kafka и SQS.
Какие плюсы и минусы message queue?
У очередей сообщений множество преимуществ: автономность процессов и асинхронность, распределенность, легкая масштабируемость, эффективное использование ресурсов, приспособленность к многопоточности… Из минусов: не всем проектам нужно это решение. Оно усложняет архитектуру сервера и требует более высокой квалификации разработчиков (а значит и более высоких трат на рекрутинг и заработные платы специалистов).
Зачем нужны очереди сообщений в микросервисной архитектуре: разбираем преимущества и недостатки
При проектировании микросервисов часто возникает вопрос: какой способ связи между ними выбрать.
Многие отдают предпочтение RESTful API. Однако этот подход не всегда эффективен, так как в отдельных случаях чреват долгим ожиданием на клиентской стороне и потерей информации в случае сбоев.
Мы расскажем про такой вариант для взаимодействия микросервисов, как очереди сообщений, а также попытаемся выяснить, для каких сценариев они подходят лучше всего. Разобраться в вопросе нам помог Павел Юдин, руководитель команды облачных продуктов, Tarantool / VK.
Sync vs Async: синхронное и асинхронное взаимодействие
Очереди сообщений (Message Queue) — это форма асинхронной коммуникации между сервисами. Поэтому, прежде чем говорить о них, покажем на упрощенном, немного искусственном примере разницу между синхронным и асинхронным взаимодействием.
Предположим, вы разрабатываете сайт книжного магазина и у вас есть сервис, к которому обращается пользователь, например отправка рецензии на прочитанную книгу. При нажатии кнопки «Отправить» вызывается некоторый API, который, в свою очередь, может обратиться к другим API.
При синхронном взаимодействии все запросы в этой цепочке вызовов выполняются строго друг за другом, а при выполнении последнего запроса ответы последовательно передаются в обратном направлении. В итоге пользователь вынужден пару секунд ждать сообщения о публикации своего отзыва, хотя его не интересуют особенности серверной обработки и он вполне обоснованно хочет увидеть сообщение сразу после нажатия кнопки. Конечно, время ожидания будет во многом определяться мощностью оборудования, но при пиковых нагрузках оно может стать серьезной проблемой.
Еще один недостаток такой схемы — обработка сбоев. Если на одном из шагов возникнет исключение, оно каскадно возвратится назад, и пользователь получит уведомление об ошибке с просьбой повторно отправить рецензию. Вряд ли кого-то обрадует получение подобного сообщения после длительного ожидания.

Описанную схему можно изменить, добавив асинхронные вызовы. Достаточно вызвать в асинхронном режиме первый REST API и параллельно вернуть пользователю сообщение о том, что его рецензия принята и будет размещена, например, в течение суток. В итоге сайт не блокируется, а вызовы всех последующих API происходят независимо от пользователя.
Но у такой схемы также есть существенный недостаток: в случае сбоя в одном из API информация, введенная пользователем, будет потеряна. Если в первом примере в случае ошибок достаточно повторно отправить рецензию, то здесь ее необходимо заполнить заново.

Для устранения недостатков обеих схем как раз и предназначены очереди сообщений.
Принципы работы очередей сообщений
Очереди предоставляют буфер для временного хранения сообщений и конечные точки, которые позволяют подключаться к очереди для отправки и получения сообщений в асинхронном режиме.
В сообщениях могут содержаться запросы, ответы, ошибки и иные данные, передаваемые между программными компонентами. Компонент, называемый производителем (Producer), добавляет сообщение в очередь, где оно будет храниться, пока другой компонент, называемый потребителем (Consumer), не извлечет сообщение и не выполнит с ним необходимую операцию.

Очереди поддерживают получение сообщений как методом Push, так и методом Pull:
- метод Pull подразумевает периодический опрос очереди получателем по поводу наличия новых сообщений;
- метод Push — отправку уведомления получателю в момент прихода сообщения. Второй метод реализует модель «Издатель/Подписчик» (Publisher/Subscriber).
Так как очереди могут использоваться несколькими производителями и потребителями одновременно, обычно их реализуют с помощью дополнительной системы, называемой брокером. Брокер сообщений (Message Broker) занимается сбором и маршрутизацией сообщений на основе предопределенной логики. Сообщения могут передаваться с некоторым ключом — по этому ключу брокер понимает, в какую из очередей (одну или несколько) должно попасть сообщение.
Вернемся к примеру с отправкой рецензии. Пусть та часть сервиса, к которому обращается пользователь, выступит в качестве производителя и будет направлять запросы на создание рецензий в очередь. Сразу после добавления сообщения в очередь пользователю можно направлять уведомление об успехе операции. Вся последующая логика обработки будет выполняться независимо от него на стороне потребителя, подписанного на очередь.
Завершив обработку, потребитель отправит подтверждение в очередь, после чего исходное сообщение будет удалено. Но если во время обработки произойдет сбой и подтверждение не будет получено вовремя, сообщение может быть повторно извлечено потребителем из очереди.
Таким образом, использование очередей сообщений решает сразу две задачи: сокращает время ожидания пользователя за счет асинхронной обработки и предотвращает потерю информации при сбоях. Но не следует рассматривать очереди как универсальное средство для любого вида приложений: как и у любого инструмента, у них есть свои преимущества и недостатки, о которых мы поговорим ниже.
Польза и преимущества очередей сообщений в микросервисной архитектуре
Используя очереди сообщений в качестве основного средства взаимодействия микросервисов (Microservices Communication), можно добиться следующих преимуществ:
Отделение логически независимых компонентов друг от друга (Decoupling)
Отличительная черта микросервисов — их автономность. И очереди во многом помогают уменьшить зависимости между ними. Каждое сообщение, передаваемое в очереди, — это всего лишь массив байтов с некоторыми метаданными. Метаданные нужны для направления в конкретную очередь, а информация, содержащаяся в основной части (теле) сообщения, может быть практически любой. Брокер не анализирует данные, он выступает лишь в качестве маршрутизатора. Это позволяет настроить взаимодействие между компонентами, работающими даже на разных языках и платформах.
Улучшение масштабируемости
Очереди сообщений упрощают независимое масштабирование микросервисов. Наблюдая за состоянием очередей, можно масштабировать те сервисы, на которые приходится большая часть нагрузки. Кроме этого, очереди легко позволяют не только увеличивать число экземпляров существующих сервисов, но и добавлять новые с минимальным временем простоя. Все, что для этого требуется, — добавить нового потребителя, прослушивающего события в очереди. Однако сами очереди также необходимо масштабировать, и это может создать дополнительные сложности.
Балансировка нагрузки
Если один из сервисов не справляется с нагрузкой, требуется возможность запускать больше его экземпляров быстро и без дополнительных настроек. Обычно для этих целей используют балансировщик нагрузки, интегрированный с сервером обнаружения служб и предназначенный для распределения трафика. При использовании очередей сообщений сам брокер по умолчанию является балансировщиком нагрузки. Если несколько потребителей слушают очередь одновременно, сообщения будут распределяться между ними в соответствии с настроенной стратегией.
Повышение надежности
Выход из строя одного из компонентов не сказывается на работе всей системы: при восстановлении он обработает сообщение, находящееся в очереди. Ваш веб-сайт по-прежнему может работать, даже если задерживается часть обработки заказа, например, из-за проблем с сервером БД или системой электронной почты. Правда, при этом очередь сама приобретает статус SPoF (Single Point Of Failure), поэтому необходимо заранее предусмотреть действия на случай ее аварийного отключения.
Безопасность
Большинство брокеров выполняют аутентификацию приложений, которые пытаются получить доступ к очереди, и позволяют использовать шифрование сообщений как при их передаче по сети, так и при хранении в самой очереди. Таким образом, очередь снимает с ваших сервисов бремя организации авторизации запросов.
Варианты использования очередей сообщений
Очереди сообщений полезны в тех случаях, где возможна асинхронная обработка. Рассмотрим наиболее частые сценарии использования очередей сообщений (Message Queue use Cases):
Фоновая обработка долгосрочных задач на веб-сайтах
Сюда можно отнести задачи, которые не связаны напрямую с основным действием пользователя сайта и могут быть выполнены в фоновом режиме без необходимости ожидания с его стороны. Это обработка изображений, преобразование видео в различные форматы, создание отзывов, индексирование в поисковых системах после изменения данных, отправка электронной почты, формирование файлов и так далее.
Буферизация при пакетной обработке данных
Очереди можно использовать в качестве буфера для некоторой массовой обработки, например пакетной вставки данных в БД или HDFS. Очевидно, что гораздо эффективнее добавлять сто записей за раз, чем по одной сто раз, так как сокращаются накладные расходы на инициализацию и завершение каждой операции. Но для стандартной архитектуры может стать проблемой генерация данных клиентской службой быстрее, чем их может обработать получатель. Очередь же предоставляет временное хранилище для пакетов с данными, где они будут храниться до завершения обработки принимающей стороной.
Отложенные задачи
Многие системы очередей позволяют производителю указать, что доставка сообщений должна быть отложена. Это может быть полезно при реализации льготных периодов. Например, вы разрешаете покупателю отказаться от размещения заказа в течение определенного времени и ставите отложенное задание в очередь. Если покупатель отменит операцию в указанный срок, сообщение можно удалить из очереди.
Сглаживание пиковых нагрузок
Помещая данные в очередь, вы можете быть уверены, что данные будут сохранены и в конечном итоге обработаны, даже если это займет немного больше времени, чем обычно, из-за большого скачка трафика. Увеличить скорость обработки в таких случаях также возможно — за счет масштабирования нужных обработчиков.
Гарантированная доставка при нестабильной инфраструктуре
Нестабильная сеть в сочетании с очередью сообщений создает надежный системный ландшафт: каждое сообщение будет отправлено, как только это будет технически возможно.
Упорядочение транзакций
Многие брокеры поддерживают очереди FIFO, полезные в системах, где важно сохранить порядок транзакций. Если 1000 человек размещают заказ на вашем веб-сайте одновременно, это может создать некоторые проблемы с параллелизмом и не будет гарантировать, что первый заказ будет выполнен первым. С помощью очереди можно определить порядок их обработки.
Сбор аналитической информации
Очереди часто применяют для сбора некоторой статистики, например использования определенной системы и ее функций. Как правило, моментальная обработка такой информации не требуется. Когда сообщения поступают в веб-службу, они помещаются в очередь, а затем при помощи дополнительных серверов приложений обрабатываются и отправляются в базу данных.
Разбиение трудоемких задач на множество маленьких частей
Если у вас есть некоторая задача для группы серверов, то вам необходимо выполнить ее на каждом сервере. Например, при редактировании шаблона мониторинга потребуется обновить мониторы на каждом сервере, использующем этот шаблон. Вы можете поставить сообщение в очередь для каждого сервера и выполнять их одновременно в виде небольших операций.
Прочие сценарии, требующие гарантированной доставки информации и высокого уровня отказоустойчивости
Это обработка финансовых транзакций, бронирование авиабилетов, обновление записей о пациентах в сфере здравоохранения и так далее.
Сложности использования и недостатки очередей сообщений: как с ними справляться
Несмотря на многочисленные преимущества очередей сообщений, самостоятельное их внедрение может оказаться довольно сложной задачей по нескольким причинам:
- По сути, это еще одна система, которую необходимо купить/установить, правильно сконфигурировать и поддерживать. Также потребуются дополнительные мощности.
- Если брокер когда-либо выйдет из строя, это может остановить работу многих систем, взаимодействующих с ним. Как минимум необходимо позаботиться о резервном копировании данных.
- С ростом числа очередей усложняется и отладка. При синхронной обработке сразу очевидно, какой запрос вызвал сбой, например, благодаря иерархии вызовов в IDE. В очередях потребуется позаботиться о системе трассировки, чтобы быстро связать несколько этапов обработки одного запроса для обнаружения причины ошибки.
- При использовании очередей вы неизбежно столкнетесь с выбором стратегии доставки сообщений. В идеале сообщения должны обрабатываться каждым потребителем однократно. Но на практике это сложно реализовать из-за несовершенства сетей и прочей инфраструктуры. Большинство брокеров поддерживают две стратегии: доставка хотя бы раз (At-least-once) или максимум раз (At-most-once). Первая может привести к дубликатам, вторая — к потере сообщений. Обе требуют тщательного мониторинга. Некоторые брокеры также гарантируют строго однократную доставку (Exactly-once) с использованием порядковых номеров пакетов данных, но даже в этом случае требуется дополнительная проверка на стороне получателя.
Хорошая новость в том, что многие облачные провайдеры сейчас предлагают очереди как сервис (MQ as a Service). Поэтому если у вас недостаточно ресурсов для самостоятельной настройки и поддержки очередей сообщений, то можно воспользоваться одним из готовых решений. Большинство из них включает автоматизацию настройки, масштабирование, диагностику ошибок и техническую поддержку, а также поддерживает строго однократную доставку в очередях FIFO.
В каких случаях очереди неэффективны
Конечно, очереди не являются универсальным средством для любых приложений. Рассмотрим варианты, когда очереди не будут самым эффективным решением:
- У вашего приложения простая архитектура и функции, и вы не ожидаете его роста. Важно понимать, что очереди сообщений — это дополнительная сложность. Эту систему также необходимо настраивать, поддерживать, осуществлять мониторинг ее работы и так далее. Да, можно использовать Managed-решение, но вряд ли это будет оправдано для небольших приложений. Добавление очередей должно упрощать архитектуру, а не усложнять ее.
- Вы используете монолитное программное обеспечение, в котором развязка (Decoupling) невозможна или не приоритетна. Если вы не планируете разбивать монолит на микросервисы, но вам требуется асинхронность — для ее реализации обычно достаточно стандартной многопоточной модели. Очереди могут оказаться избыточным решением до тех пор, пока не возникнет явная необходимость в разделении приложения на автономные компоненты, способные независимо выполнять задачи.
Выбирая инструмент для будущего приложения, обязательно взвесьте все за и против. Не стоит использовать очереди сообщений для задач, которые могут быть решены другим, более простым в настройке и обслуживании способом. Но в тех случаях, когда запланирован переход на микросервисы и бизнес-логика допускает возможность асинхронной обработки, очереди сообщений могут стать лучшим выбором для повышения производительности и надежности вашего продукта.
Если вы заинтересованы в использовании очередей, но опасаетесь, что команда не справится с их конфигурированием и последующей поддержкой самостоятельно, всегда можно воспользоваться одним из Managed-решений, представленных на рынке.
Очередь сообщений
До сих пор мы говорили о сборе данных, сейчас обсудим как собранные данные передаются в систему анализа и дальше по цепочке.
Вспоминая общую схему потоковой системы, речь будет идти о компоненте очереди сообщений.
Необходимость очереди сообщений
Может возникнуть резонный вопрос, а зачем вообще звено очереди сообщений? Ведь если рассматривать обработку данных в пределах одной машины, данные из компонента сбора данных можно сразу передавать в звено анализа, и всё будет работать.
Ответ достаточно прост – при обработке больших массивов данных, речь чаще всего идёт о распределённых системах. Распределённые системы значительно проще строить и поддерживать в отсутствие сильных связей между компонентами (и вообще сложные системы!). Поэтому, чтобы разорвать сильную связь между компонентом сбора данных и компонентом анализа, мы вводим между ними промежуточную “прослойку”. Использование очереди сообщений позволяет нам работать на более высоком уровне абстракции – передавать сообщения, а не вызывать явно следующее звено.
Основные концепции
Определимся, что именно мы понимаем под очередями сообщений. Здесь этот термин понимается в широком смысле. Существует множество программных продуктов, реализующих абстракцию очереди сообщений (“брокеры сообщений”):
Вообще, проект Apache Kafka имеет больше возможностей, чем просто реализация очереди сообщений, но здесь мы временно про это забудем, и ограничимся рассмотрением возможностей публикации/подписки на потоки сообщений, что достаточно близко к абстракции очереди.
Компоненты очереди сообщений
В очереди сообщений есть три главных компонента:
- Производитель сообщений
- Брокер сообщений
- Потребитель сообщений
Задачи производителя и потребителя точно отражены в их названиях: производитель порождает сообщения, а потребитель их потребляет.
Обратим внимание, что вместо “очередь сообщений” на схеме написано “брокер”. Разница в том, что брокер может управлять несколькими очередями. Очереди абстрагируются брокером.
На этой схеме более очевидно, что происходит:
- Производитель отправляет сообщение брокеру
- Брокер получает сообщение и помещает его в очередь
- Потребитель запрашивает сообщение у брокера
- Брокер достаёт сообщение из очереди и передаёт потребителю
В целом всё выглядит достаточно просто и интуитивно, но обсудим подробности, которые могут быть не очень очевидны.
Изоляция производителей и потребителей
Одна из наших целей – ослабить связи между компонентами. Очередь сообщений делает это для компонентов сбора данных и анализа. Обсудим, почему именно это желательно и какие преимущества это даёт.
В зависимости от характера задачи, может оказаться, что производитель порождает сообщения быстрее, чем потребитель из может принять. Как в таком случае предотвратить “захлёбывание” компонента анализа?
Здесь отметим, что “избыточность” сообщений называется “противодавлением”, по аналогии с гидравлическими системами. Когда всё идёт хорошо, и сообщения обрабатываются быстрее, чем производятся, противодавление равно нулю. Когда же сообщения производятся быстрее, чем обрабатываются, “противодавление” растёт.
Во многих системах временный рост противодавления – абсолютно нормальное явление. Например, в пакетных системах обработки данных, потребители сообщений периодически подключаются, собирают все скопившиеся сообщения, и обрабатывают их, а между подключениями противодавление растёт. Однако в системах “почти” реального времени, рост противодавления может свидетельствовать о проблемах.
Можно предположить, что противодавлением можно управлять на стороне потребителей – если оно растёт, можно увеличить число потребителей или сделать их быстрее, чтобы они справлялись с потоком производимых сообщений. Но это не всегда может быть оправдано. В других системах, контроль противодавления осуществляется через управление производителем.
Следует отметить, что не все системы очередей сообщений поддерживают управление производителем. Тогда темп порождения сообщений остаётся целиком на совести разработчика конечного приложения. Поддержка медленных и/или периодически отключающихся потребителей в основном имеется в продуктах, в которых реализованы т.н. долговечные сообщения.
Долговечные сообщения
Долговечные сообщения могут быть интересны не только с точки зрения управления противодавлением. Представим себе, что звено сбора данных и звено анализа географически разнесены. Всё идёт хорошо, но вдруг вечером пятницы происходит авария (например, какой-нибудь экскаватор порвал оптоволоконный кабель – что уже неоднократно случалось) и связь между звеньями стала гораздо медленнее, так что весь поток сообщений перестал через неё проходить.

Как это отразится на бизнесе? Сколько данных можно потерять без катастрофических последствий? Если потеря данных недопустима, то нужна технология очереди, которая способна хранить сообщения в течение длительного времени. Это реализуется путём записи сообщений в долговременное хранилище.
Конкретные реализации долговременного хранилища очереди сообщений могут быть различными. Это может быть ФС (возможно, распределённая), или реплицируемая база данных, или даже какое-то стороннее коммерческое решение, но общий смысл один – долгосрочно надёжно хранить сообщения, которые не удаётся передать “прямо сейчас”.
Долговечные сообщения не только в какой-то мере обеспечивают устойчивость к сбоям, но и дают возможность поддержки периодически активных потребителей. Это может быть интересно и в разрезе систем потоковой обработки данных, если нам хочется обрабатывать одни и те же даныне по-разному.
Представим себе такой пример: мы разрабатываем систему навигации для водителей (типа Яндекс.Навигатор), позволяющую строить маршруты на основе текущей дорожной обстановки. Спустя некоторое время, принято решение добавить возможность воспроизведения прошлой дорожной обстановки (например, для обучения нейросети, предсказывающей дорожную обстановку в будущем, или просто для удобства конечных пользователей). В отсутствие долговечных сообщений, в системе “почти” реального времени, принятые звеном анализа сообщения удаляются из очереди сообщений, и вернуться в прошлое уже не получится. С другой стороны, если одна или несколько очередей записываются в хранилище, то потребители исторических данных могут подключаться и обрабатывать эти сообщения по мере наличия ресурсов (после чего записывать результаты обработки в постоянное хранилище).
Семантика доставки сообщений
Производитель отправляет сообщения брокеру, а потребитель запрашивает сообщения у брокера. Это очень поверхностное описание того, как работает механизм доставки сообщений. Копнём теперь глубже и посмотрим, какие гарантии дают продукты, реализующие очереди сообщений.
Есть три вида таких гарантий:
- Не более одного раза – сообщение может потеряться, но никогда потребитель не получит одно и то же сообщение дважды.
- Не менее одного раза – сообщение не может потеряться, но может быть больше одного раза получено потребителем
- Ровно один раз – сообщение не может потеряться и потребитель читает его ровно один раз
Какое решение лучшее? Интуитивно кажется, что “ровно один раз”, и это популярная версия ответа на этот вопрос: большинство хочет иметь сильные гарантии корректности. Однако системы, дающие такие гарантии, сложны, не слишком производительны, и имеют множество возможных точек отказа. Всё не так мрачно, но это стоит иметь ввиду.
Рассмотрим возможные точки отказа в системе, гарантирующей доставку “только один раз”:
- Производитель – если производитель отказывает после того, как сообщение сгенерировано, но до того, как оно отправлено брокеру, сообщение будет потеряно. Или если производитель отказывает, ожидая подтверждения приёма сообщения от брокера, после восстановления он отправит повторно то же самое сообщение
- Сеть между производителем и брокером – если выходит из строя сеть между производителем и брокером, то сообщение, отправленное производителем не дойдёт до брокера. Или если по причине ошибки сети подтверждение не дойдёт до производителя, сообщение отправится повторно.
- Брокер – если брокер отказывает, когда сообщения ещё не сохранены в надёжном хранилище, сообщения будут потеряны. Если брокер отказывает, не успев послать подтверждение производителю, сообщение будет отправлено повторно. Аналогично на стороне потребителя.
- Очередь сообщений – если очередь сообщений абстрагирует постоянное хранилище, то в случае отказа при попытке записи на диск, сообщения могут быть потеряны
- Сеть между потребителем и брокером – возможна потеря сообщения или подтверждения доставки, соответственно потеря или повторная отправка сообщения
- Потребитель – отказ потребителя может привести к необходимости повторной отправки сообщения; при наличии нескольких потребителей одно сообщение может быть доставлено нескольким потребителям повторно
Для систем, гарантирующих доставку хотя бы один раз или не больше одного раза, число сценариев отказа по понятным причинам уменьшается вдвое. Что выбрать – зависит от конкретной задачи, в любом случае приходится искать компромисс между скоростью и корректностью. Если создаётся проект для веб-аналитики, то разумным выглядит решение “не более одного раза” – потеря небольшой части сообщений скорее всего не слишком исказит статистику (повторные сообщения сделают это с большей вероятностью), а система может быть проще и производительнее (а значит, дешевле). Если же речь идёт об обнаружении случаев финансового мошенничества, то может быть имеет смысл система, дающая гарантию “ровно один раз”, чтобы не пропустить мошеннические операции с одной стороны и избежать ложно-позитивных срабатываний системы из-за повторных сообщений с другой.
При изучении систем сообщений, может выясниться, что подходящая по всем прочим параметрам система (например Kafka или ActiveMQ) не даёт гарантий “только один раз”. Это не фатально – часто системы очередей сообщений предоставляют достаточно метаданных, чтобы можно было реализовать семантику однокаратной доставки самостоятельно через координацию производителей и потребителей (это однако усложнит систему за счёт “протекающей” абстракции – абстракция очереди сообщений будет частично “размазана” между производителем и потребителем):
- Со стороны производителя. Не пытаться отправить сообщения повторно. Для этого нужно каким-то образом запоминать, какие сообщения производители отправляют брокерам. Если ответ от брокера не поступил или сетевое соединение оборвалось, то после восстановления можно получить данные от брокера и проверить, было ли получено сообщение, для которого не пришло подтверждение. Такой подход (в разумных пределах) гарантирует, что сообщения отправляются производителем только один раз
- Со стороны потребителя. Сохранять метаданные последнего сообщения. Нужно хранить такие данные о сообщениях, которые позволят однозначно определить, что потребитель не обрабатывает сообщения повторно. Обычно у сообщений есть некий идентификатор, позволяющий их однозначно определить. Метаданные должны сохраняться в надёжное постоянное хранилище.
Отдельно следует отметить, что хранить может быть полезно не только идентификатор сообщения, но и метаданные, позволяющие определить полезную нагрузку этого сообщения. Тогда кроме гарантий однократной доставки, можно почти “бесплатно” получить возможность аудита данных (проверки корректности)
Безопасность
В рамках этого курса мы не слишком акцентируем внимание на безопасности, но про неё не следует забывать. Конкретно при обсуждении очередей сообщений, следует не только следить за безопасностью данных при передачи и хранении, но также и за тем, разрешено ли конкретным производителям данных порождать соответствующие сообщения, а конкретным потребителям – потреблять. Иначе возможна ситуация, что скомпрометированный производитель значительно искажает данные, или скомпрометированный потребитель получает все данные из системы.
Как минимум, нужно продумать все эти моменты, и если в команде есть безопасники, подключить их к этому.
Моменты, на которые стоит обратить внимание:
- На этапе сбора данных:
- Можно ли аутентифицировать производителя?
- Разрешено ли производителю порождать сообщения, которые он порождает?
- Как обеспечить безопасность передачи (сильное шифрование; насколько сильное?)
- Как обеспечить безопасность хранения (сильное шифрование, криптографические подписи)
- Если очередь распределённая, могут ли брокеры аутентифицировать друг друга?
- Можно ли аутентифицировать потребителя?
- Разрешено ли потребителю потреблять сообщения, которые он потребляет?
Отказоустойчивость
Теперь обсудим, что произойдёт с данными, когда случится что-то нехорошее. Не если случится – когда. Рассчитывать на безотказную работу ни в коем случае нельзя.
Что случится, если один из брокеров выйдет из строя? Если брокер использует долговременное хранилище, то можно надеяться, что риску подвержены только сообщения, которые брокер не успел туда записать. Есть несколько способов снижения связанных с этим рисков:
- Производитель может ожидать подтверждения записи сообщений на диск
- Можно реплицировать сообщения нескольким брокерам. Риск остаётся, но с ростом числа брокеров в репликации риск падает экспоненциально (вероятность одновременного отказа двух одинаковых узлов – это вторая степень вероятности отказа одного узла)
- Можно хранить в оперативной памяти как можно меньше данных. Этот подход чреват заметными потерями производительности, т.е. опять компромисс между производительностью и надёжностью
Что случится в случае разрыва сетевых соединений? При использовании систем сообщений, поддерживающих репликацию, данные в относительной безопасности, поскольку хранятся на нескольких узлах (брокерах). После восстановления связности сети, брокер снова присоединится к кластеру и синхронизируется с другими брокерами. При выборе продукта, следует найти ответы как минимум на следующие вопросы:
- При отказе сети, выбирается ли в качестве реплики другой брокер?
- Что происходит при восстановлении сети?
- Есть ли возможность настроить временную задержку (“таймаут”), при которой считается, что сеть отказала?
- Что произойдёт с данными, если сеть не восстановится?
- Что произойдёт с данными, если брокер отключится от кластера в момент передачи ему сообщения от производителя?
Что произойдёт при отказе хранилища? Хотя такая ситуация грозит катастрофической потерей данных, любой, кто имел дело с СХД, знает, что с этим можно бороться. Если задействовано несколько брокеров, следует найти ответы на вопросы:
- Существуют ли реплики потерянных в результате отказа СХД данных?
- Если реплицируемые данные не успели записать на диск до момента отказа: будут ли эти данные потеряны?
- Как восстановить брокера после отказа СХД?
Оценивая пригодность конкретного продукта для решения задач бизнеса, следует поставить эти вопросы и найти на них ответы.
Примеры применения в конкретных задачах
Посмотрим, как можно применить базовые концепции в рамках конкретных (умеренно фантазийных) сценариев.
Финансы: обнаружение мошенничества
Компания “ООО”Петров и ко»» предоставляет службу обнаружения мошенничества в реальном времени. Для этого собираются сведения об операциях по кредитным картам из всех доступных источников, к данным применяются различные хитроумные алгоритмы (являющиеся предметом коммерческой тайны) и в момент совершения покупки клиентам этой системы отправляется решение об одобрении или отклонении операции.
Вот некоторые вопросы, которыми необходимо задаться при проектировании такой системы:
- Как повлияет на бизнес длительное отсутствие связи между звеньями сбора данных и анализа?
- Ответ: катастрофически. Компания не сможет обеспечивать сервис, который продаёт, и это может нести не только репутационные потери, но и прямые финансовые потери со стороны заказчиков.
- Ответ: нельзя. Вообще, с учётом характера приложения, потери данных – практически недопустимы.
- Ответ: Скорее всего, да. Во-первых, эти данные могут быть важны при отладке и доработке алгоритмов анализа. Во-вторых, в случае претензий со стороны заказчиков, исторические данные могут быть крайне важны для решения спорных моментов. В-третьих, заказчикам могут быть интересны подробные отчёты о работе службы за какой-то преиод времени.
- Ответ: Скорее всего, “ровно один раз”. Как минимум, недопустима потеря сообщений. Можно ли обойтись семантикой “не менее одного раза”? Возможно. Но это сильно усложнит алгоритмы анализа или как минимум часть системы анализа, отвечающую за получение сообщений от брокера.
Интернет вещей: “социальные” автоматы для продажи лимонада
Пусть компания “ООО”Сидоров и ко»» принадлежат автоматы для продажи прохладительных напитков. Допустим, руководство приняло стратегическое решение активной рекламы через отправку твитов и push-уведомлений со специальными предложениями находящимся поблизости потребителям. К тому же, если в одном из автоматов закончился товар, он должен рекомендовать другой автомат поблизости, который может предложить выгодную (в первую очередь компании) сделку.
- Как повлияет на бизнес длительное отсутствие связи между звеньями сбора данных и анализа? Если та же система используется для управления запасами в торговых автоматах, как это изменит ответ на вопрос?
- Данные за сколько дней можно потерять без последствий?
- Должны ли храниться старые данные?
- Какая семантика доставки сообщений нужна в этом случае?
- Что случится, если одно сообщение будет обработано несколько раз? Если сообщение будет пропущено?
Электронная коммерция: рекомендация товаров
Компания “ООО”Петров и ко»» занимается торговлей модной одеждой и ищет способы повысить конверсию посетителей сайта в покупателей. Отдел маркетинга уверяет, что социальные методики крайне действенные. Вас нанимают спроектировать и разработать систему, которая будет показывать посетителям сайта, что другие посетители недавно положили в свою корзину или купили. Например, если я открыл страницу товара “джинсы”, а другие покупатели вместе с такими же джинсами клали в корзину ботинки или рубашку, то я должен увидеть рекомендацию в ключе
Пять человек добавили в корзину вместе с этими джинсами ещё и
К системе можно предъявить следующие требования:
- Отслеживать все покупки в (почти) реальном времени
- Отслеживать корзины всех покупателей в (почти) реальном времени
- На странице каждого товара показывать, какие товары недавно куплены вместе с ним
- На странице каждого товара показывать, какие товары находятся вместе с ними в корзинах других покупателей
- Как повлияет на бизнес длительное отсутствие связи между звеньями сбора данных и анализа?
- Данные за сколько дней можно потерять без последствий?
- Должны ли храниться старые данные?
- Какая семантика доставки сообщений нужна в этом случае?
Очереди сообщений
Очередь сообщений — это инфраструктура обмена сообщениями между приложениями. Сообщения собираются от различных программ и ставятся в очередь на отправку, сортировку и дальнейшее распределение по программам.
Работа с очередями сообщений доступна только в редакции ELMA Enterprise .
В ELMA4 можно работать со следующими типами очередей:
- RabbitMQ — платформа, которая реализует обмен сообщениями между компонентами программной системы на основе стандарта AMQP (Advanced Message Queuing Protocol) и выпускается под Mozilla Public License;
- MSMQ (Microsoft Message Queuing Services) — стандарт очереди сообщений, входящий в стандартную поставку Microsoft Windows;
- JMS (Java Message Service) — протокол обмена сообщениями между приложениями, содержащий Java API. Позволяет приложениям создавать, отправлять, получать и читать сообщения. Для работы используется сервер WebLogic JMS.
Работа с очередями сообщений осуществляется в дизайнере в разделе Очереди сообщений .
Все настроенные очереди отображаются в таблице.

Чтобы добавить новую очередь сообщений, нажмите кнопку + Очередь и заполните поля. В настройках нужно указать название и выбрать тип очереди (RabbitMQ, MSMQ или JMS). Набор полей для заполнения зависит от типа очереди.
Если вы хотите изменить настройки, нажмите на название очереди в таблице.
Чтобы удалить очередь, нажмите .
Настройки очереди сообщений типа RabbitMQ
Для корректной настройки и работы очереди сообщений типа RabbitMQ должен быть установлен и доступен сервер RabbitMQ. Подробнее об этом читайте статью в Базе знаний.
Ниже на рисунке представлены настройки очереди.

Хост * — IP-адрес или наименование сервера RabbitMQ, к которому вы подключаетесь (например, localhost).
Порт — порт подключения к серверу. По умолчанию используется порт 5672.
Виртуальный хост * — хост, указанный в настройках сервера RabbitMQ. По умолчанию рекомендуется использовать «/».
Имя точки доступа * — имя точки доступа, которое указано в настройках сервера RabbitMQ на вкладке Exchanges .
Имя очереди * — имя очереди, которое указано в настройках сервера RabbitMQ на вкладке Queues .
Логин * — логин пользователя для подключения к серверу RabbitMQ.
Пароль * — пароль пользователя для подключения к серверу RabbitMQ.
Тайм-аут — время ожидания получения сообщения по очереди (в секундах). По умолчанию — 10 секунд.
Чтобы обеспечить безопасность при обмене сообщениями, можно использовать TLS-соединение. Для этого установите флажок Включить и заполните поля в блоке Настройки TLS .
Пароль для клиентского сертификата — указание пароля клиентского сертификата.
Имя сервера — имя сервера RabbitMQ, которое должно соответствовать записям SAN (Subject Alternative Name) или CN (Common Name) сертификата сервера.
Путь до клиентского сертификата — путь до клиентского сертификата, который используется для проверки на стороне клиента. Сертификат имеет формат PKCS12.
По умолчанию включена опция Клиентская верификация сертификата . Не рекомендуется выключать ее в продуктивных средах.
Настройки очереди сообщений типа MSMQ
Очереди сообщений типа MSMQ могут быть общие и частные. Подробнее об этом можно прочитать в статье в Базе знаний.
Ниже на рисунке представлены настройки очереди.

Строка подключения * — строка подключения, в которой задаются основные параметры подключения (протокол, имя сервера, к которому нужно подключиться, тип очереди, имя очереди). Вы можете ознакомиться с особенностями указания строки подключения, нажав :
- подключение к очереди производится от имени пользователя Windows, под которым работает сервер ELMA4;
- доступ к очередям регулируется сервером очередей сообщений.
Варианты строки подключения:
- .\private$\local_name_queue — подключение к частной очереди на локальном компьютере;
- FormatName:DIRECT=OS:server01\QueueName — прямое имя общей очереди на компьютере server01;
- FormatName:DIRECT=OS:ws02\private$\QueueName — прямое имя частной очереди на компьютере ws02.
Настройки очереди сообщений типа JMS
Для корректной настройки и работы очереди сообщений типа JMS должен быть установлен сервер JMS.
Ниже на рисунке представлены настройки очереди.

Адрес и порт * — адрес и порт сервера сообщений JMS в формате t3://localhost: , где:
- localhost — адрес сервера JMS;
- адрес порта — номер порта сервера JMS.
Имя очереди * — имя очереди, указанное в настройках сервера JMS.
ConnectionFactory * — объект на сервере сообщений, инкапсулирующий ряд параметров конфигурации соединения, который определяется администратором сервера. Предназначен для создания соединения с провайдером JMS.
Логин * — логин пользователя для подключения к очереди сообщений.
Пароль * — пароль пользователя для подключения к очереди сообщений.
Проверка
Для всех типов очередей отображается блок Проверка , в котором можно указать тестовое сообщение, которое отправляется для проверки корректности заданных настроек. Чтобы отправить тестовое сообщение на сервер, нажмите кнопку Отправить тестовое сообщение . В открывшемся окне вы увидите информацию о доступности сервера.
После того как вы создали очереди сообщений, их можно использовать при моделировании процессов.
Нашли опечатку? Выделите текст, нажмите ctrl + enter и оповестите нас