что такое очередь сообщений
RabbitMQ. Часть 3. Разбираемся с Queues и Bindings
Queue (очередь) — структура данных на диске или в оперативной памяти, которая хранит ссылки на сообщения и отдает их копии consumers (потребителям). Queue представляет собой Erlang-процесс с состоянием (где могут кэшироваться и сами сообщения). 1 тысяча очередей может занимать порядка 80Mb.
Binding (привязка) — правило, которое сообщает обменнику в какую из очередей должны попадать сообщения.
Оглавление
Временные очереди
Постоянные очереди
Highly Available очереди
Очереди HA требуют кластерной среды RabbitMQ. В кластерном режиме вся информация об обменниках, очередях, привязках и потребителях будет скопирована на все узлы.
Когда сообщение публикуется в какую-то HA очередь, оно хранится на каждом узле, относящемуся к HA очереди. После того как сообщение потребляется на каком-то из узлов, все копии этого сообщения будут удалены на других узлах.
Очереди HA могут распространяться на все узлы в некотором кластере или только на индивидуальные.
Создание очереди
Пример создания очереди при помощи RabbitMQ.Client:
arguments
Повторный вызов Queue.Declare с аналогичными параметрами вернет полезную информацию об этой очереди. Например, общее число сообщений, находящихся в ожидании в данной очереди, и общее число подписанных на неё потребителей.
Вызов Queue.Declare под учетными данными пользователя, которому не назначены необходимые права закроет канал при помощи команды Channel.Close и клиент получит исключение OperationInterruptedException, которое будет содержать код ошибки 403 и ее описание.
После того, как очередь простаивает в течении >= 10 секунд, она впадает в спящий режим, вызывая GC в очереди, что приводит к значительному сокращению памяти, необходимой для этой очереди.
Создание Queue через графический интерфейс
Создание Binding
Пример создания привязки при помощи RabbitMQ.Client:
Создание Binding через графический интерфейс
В данном разделе опишем очередь и привязку кодом на C#, так если бы нам требовалось разработать библиотеку. Возможно это будет полезно для восприятия.
Очереди — что это, зачем и как использовать? Посмотрим на возможности AWS SQS
Сначала давайте дадим определение понятию «очередь — queue».
Возьмем для рассмотрения тип очереди «FIFO»(first in, first out). Если взять значение из википедии — «это абстрактный тип данных с дисциплиной доступа к элементам». Если вкратце, это означает что мы не можем из нее доставать данные в случайном порядке, а только забирать то — что пришло первым.
Далее, нужно определиться зачем вообще они нужны?
1. Для отложенных операций. Классическим примером является обработка картинок. К примеру пользователь загрузил на сайт картинку, которую нам нужно обработать, эта операция занимает много времени, пользователь столько ждать не хочет. Поэтому мы грузим картинку, далее передаем ее в очередь. И она будет обработана, когда какой либо «worker» ее достанет.
2. Для обработки пиковых нагрузок. К примеру, есть какая-то часть системы, на которую иногда обрушивается большой трафик и она не требует мгновенного ответа. Как вариант, генерация каких-либо отчетов. Выкидывая в очередь эту задачу — мы даем возможность обрабатывать это с равномерной нагрузкой на систему.
3. Масштабируемость. И наверное самая важная причина, очередь дает возможность
масштабироваться. Это означает, что вы можете поднять несколько сервисов для обработки параллельно, что сильно повысит производительность.
Теперь давайте рассмотрим проблемы, с которыми столкнемся, если будем создавать очередь сами:
1. Параллельный доступ. Забрать из очереди определенное сообщение может только один обработчик. То есть если одновременно два сервиса попросят сообщения, каждому из них должен вернуться уникальный набор сообщений. Иначе, получится, что одно сообщение обработается два раза. Что может быть чревато.
2. Механизм дедупликации. В сервисе должна быть система, защищающая очередь от дубликатов. Может быть ситуация, в которой случайно в очередь будет отправлено один и тот-же набор данных два раза. В итоге мы одно и тоже обработаем два раза. Что опять же чревато.
3. Механизм обработки ошибок. Допустим наш сервис забрал из очереди три сообщения. Два из которых он успешно обработал, отправив запросы на удаление из очереди. А третье он не смог обработать и умер. Сообщение которое находится в статусе обработки — недоступно для других сервисов. И оно не должно навечно остаться в статусе обработки. Такое сообщение должно передаться другому обработчику по какой-то логике. Вариант реализации такой логики мы рассмотрим скоро на примере AWS SQS(Simple Queue Service)
Amazon Web Services — Simple Queue Service
Теперь давайте рассмотрим как решает эти проблемы SQS и что он может
1. Параллельный доступ. У очереди вы можете задать параметр «Visibility timeout». Он определяет, сколько по времени максимально может длиться обработка сообщения. По умолчанию он равен 30 секундам. Когда какой-либо сервис забирает сообщение, оно переводится в статус «In Flight» на 30 секунд. Если за это время не было команды удалить это сообщение из очереди, оно возвращается в начало и следующий сервис сможет его получить для обработки еще раз.
Небольшая схемка работы.
2. Механизм обработки ошибок. В SQS можно настроить вторую очередь для «мертвых» сообщений(Dead Letter Queue). То есть те, которые не смог обработать наш сервис, будут отправляться в отдельную очередь, которой вы можете распоряжаться по своему усмотрению. Также вы можете задавать после которого кол-ва неудачных попыток сообщение перейдет в «мертвую» очередь. Неудачной попыткой считается истечение «Visibility timeout». То есть если за это время не было отправлено запроса на удаление, такое сообщение будет считаться необработанным и вернется в основную очередь или перейдет в «мертвую».
3. Дедупликация сообщений. Так же SQS имеет систему защиты от дубликатов. У каждого сообщения есть «Deduplication Id», SQS не добавит в очередь сообщение с
повторным «Deduplication Id» в течении 5 минут. Вы обязаны задавать «Deduplication Id» в каждом сообщении или включить генерацию id на основе контента. Это означает что в «Deduplication Id» будет попадать хэш сгенерированный исходя из вашего контента. Параметр «Content-Based Deduplication». Подробнее о дедупликации
Notice: Будьте внимательны, если отправить два одинаковых сообщения в течении 5 минут и у вас включен «Content-Based Deduplication» SQS не добавит второе сообщение в очередь.
Notice: Будьте внимательны, к примеру если на девайсе отпала связь, и он не получил ответ и затем отправил повторный запрос спустя 5 минут, дубликат создастся.
4. Long poll. Длительный опрос. SQS поддерживает такой тип подключения с максимальным таймаутом в 20 секунд. Что нам позволяет сэкономить на трафике и «дерганье» сервиса.
5. Метрики. Так же Amazon предоставляет подробные метрики по очередям. Такие как кол-во полученных/отправленных/удаленных сообщений, размеры в КБ этих сообщений и прочее. Также вы можете подключить SQS к сервису логов CloudWatch. Там сможете увидеть еще подробнее. Так же там можно настроить так называемые «сигналы тревоги»(Alarms) и вы можете настраивать действия по каким либо событиям. Подробнее о подключении к SQS. И Документация по CloudWatch
Теперь давайте рассмотрим настройки очереди:
Основные:
Message Retention Period — кол-во секунд/минут/часов/дней, которое означает, сколько по времени будут в очереди храниться необработанные сообщения. Максимально — 14 дней.
Maximum Message Size — максимальный размер сообщения в KB. Значение от 1KB до 256KB.
Receive Message Wait Time — время, сколько будет держаться коннект в случае, если мы используем «Long poll», для получения новых сообщений.
Content-Based Deduplication — флаг, если установлен в true, то в каждое сообщение будет добавлен «Deduplication Id» в виде SHA-256 хэша, сгенерированный из контента.
Настройки «мертвой очереди»
Use Redrive Policy — флаг, если установлен, то сообщения после нескольких попыток будут перенаправляться.
Dead Letter Queue — имя «мертвой» очереди, в которую будут отправляться необработанные сообщения.
Maximum Receives — кол-во неудачных попыток обработки, после которых сообщение будет отправляться в «мертвую» очередь
Notice: Также обратите внимание, что все основные параметры мы можем отправлять вместе с каждым сообщением отдельно. К примеру, каждое отдельное сообщение может иметь свой Visibility Timeout или Delivery Delay
Теперь немного про сами сообщения и их свойства:
Сообщение имеет несколько параметров:
Также есть атрибуты сообщений
Атрибуты состоят из имени, типа и значения.
Notice: Обратите внимание, что максимальное кол-во атрибутов 10 Подробности
Очередь сообщений (Message Queue)
Очередь сообщений (Message Queue)
Этот пост рассказывает об очередях сообщений — почему вы должны знать о них, думать при планировании архитектуры и использовать их в вашем приложении.
Почему очереди сообщений?
Сообщения, наряду с блоками вычисления и хранения, составляют три основных блока почти в каждой блок-схеме системы. Очереди сообщений, по существу, являются связующим звеном между различными процессами в ваших приложениях и обеспечивают надежный и масштабируемый интерфейс взаимодействия с другими подключенными системами и устройствами.
О́чередь — структура данных с дисциплиной доступа к элементам «первый пришёл — первый вышел». Добавление элемента возможно лишь в конец очереди, выборка — только из начала очереди, при этом выбранный элемент из очереди удаляется.
Использование очереди сообщений
Почему SaaS?
Добавление очереди сообщений для облачных приложений имеет смысл, только если есть чистый выигрыш в плане установки и эксплуатации. Добавление дополнительного архитектурного слоя отвечающего за очереди сообщений — непростая задача, особенно если вы решили использовать собственное решение или установить на свои сервера стороннее, так как это привнесёт дополнительные затраты на мониторинг, настройку, управление и повлияет на общую надёжность и безопасность системы.
Когда очереди сообщений легки в установке, просты в использовании, высоко доступны и чрезвычайно надёжны — все становиться гораздо проще.
Тут уместна аналогия получения энергии. Прогресс шёл от ветряных мельниц и угольных печей до промышленных электростанций и линий электропередач.Этот последний шаг — индустриализация энергии — изменило лик промышленности в мире. Это снизило затраты на строительство и производство, изменило города, заводы, и дома, и позволило создать новые изобретения, услуги и виды бизнеса.
Аналогичным образом, путём подключения служб очередей сообщений, разработчики больше не должны поддерживать огромный наборов сервисов, работающих на нескольких серверах и не опасаться простоя в результате отказа систем. В современном мире поставщики услуг берут на себя ответственность за управления серверами, API и другими ресурсами, а разработчик абстрагируясь от большинства физических ограничений может сконцентрироваться на реализации своей идеи.
Преимущества перехода на облачные очереди сообщений включают в себя:
С чего начать?
PS Я надеюсь мне удалось заронить каплю сомнения в выбор «поставить свой сервер MQ или использовать сторонний сервис» и заинтересовать в существующих SaaS решениях в области очередей сообщений.
Очереди сообщений в бэкенд-архитектуре: как построить надежную систему
Очереди сообщений — устоявшаяся технология, которую разработчики применяют уже много лет. Разберемся, как она работает.
Почему понадобились очереди сообщений
Серверные сообщения обычно устроены просто и однотипно: сервер получает запрос, обрабатывает его и сразу же возвращает клиенту. Схема хорошо работает до тех пор, пока обработка запроса занимает немного времени, например доли секунды.
Но бывает, что вернуть ответ клиентскому приложению сразу невозможно. Например, когда сервер обрабатывает видео — это может занять минуты и даже часы. На время обработки большого объема данных вычислительные ресурсы сервера загружены и его способность обрабатывать входящие запросы падает.
Что такое обмен серверными сообщениями и как он устроен
Допустим, серверное приложение получило тяжелый запрос. Оно передает его другим приложениям дальше по цепочке, а само продолжает общение с клиентом.
Для передачи сообщения другим приложениям используют специальный инструмент — очереди сообщений. Эта технология решает любые инфраструктурные вопросы:
Когда в вашем бэкенд-приложении задействованы очереди, обработка видео выглядит так:
Схема асинхронного обмена сообщениями между приложениями. Источник
FIFO и LIFO (ФИФО и ЛИФО) — что это такое
Сервисы обмена сообщениями между серверами делятся на два типа:
Сервисы для организации очередей сообщений
Популярные сервисы для организации очередей сообщений — RabbitMQ, Apache Kafka и Redis. Давайте посмотрим, чем они различаются.
RabbitMQ
Сервер организации очередей сообщений, написанный на языке программирования Erlang. Это распределенный и горизонтально масштабируемый брокер сообщений. Он позволяет разным программам взаимодействовать с помощью протокола AMQP, а через дополнительные модули — и с помощью некоторых других протоколов: MQTT, HTTP и так далее.
RabbitMQ — это инструмент, который силен в маршрутизации сообщений. Система поддерживает несколько видов распределения сообщений в сети, их комбинация позволяет создавать очень хитрые правила доставки сообщений.
Apache Kafka
Apache Kafka — продукт, который реализует систему распределенного журнала событий. Kafka славится своей скоростью работы и масштабируемостью. Из-за способности передавать терабайты данных эту систему очередей сообщений любят разработчики, работающие с Big Data. Например, ее используют в Airbnb, Adidas, Cisco и PayPal.
Redis
Redis создавалась как система хранения данных в оперативной памяти. Изначальное предназначение — ускорение доступа к востребованной информации и построение систем кеширования.
Но разработчики добавили в код возможность построения простых очередей и стеков. В итоге Redis применяют в качестве сервера очередей сообщений в проектах, где нужно быстро и дешево проверить инженерные гипотезы по работе с очередями.
Краткий обзор MQ (Messages queue) для применения в проектах на РНР. Часть 1
Параллельно к основной работе, я в «фоне» обдумываю и прикидываю реализации архитектуры для игровых проектов (напомню, что основная область моих интересов и работ — создание онлайновых браузерных игр). Последнее время я все чаще и чаще возвращаюсь к мысли, что интересно было бы реализовать основной игровой сервер на основе очередей сообщений (MQ или Messages queue). То есть, движок такой игры будет представлять собой набор компонентов, которые будут общаться между собой посредством асинхронных сообщений, а каждый компонент может быть как генератором сообщений, так и подписчиком, то есть исполнять другие сообщения.
Такой подход, насколько я понимаю, широко применяется в мире Java, там для этого есть стандарт Java Message Service (JMS) и применяются брокеры сообщений и на этом базируется архитектура Enterprise service bus (ESB), например, Apache ServiceMix. Но для нас это пока высокая сфера крупных проектов, а в специфике веба и веб-ориентированных приложений я бы хотел рассмотреть, можно ли что-то сделать подобное, но с меньшими затратами и обеспечить приложению отказоустойчивость, распределение нагрузки и асинхронную обработку. И конечно, очень желательно, чтобы это было реализовано на РНР как основном языке реализации всех компонентов сервера.
И так, еще раз — MQ, это архитектура и ПО промежуточного уровня, которое занимается сбором, хранение и маршрутизацией (распределением) сообщений между компонентами. Я не претендую на полноту описания, и, вполне возможно, не учитываю множества нюансов, поэтому не рассматривайте мои определения как аксиомы, лучше всего почитать дополнительную литературу, если вы хотите поглубже разобраться в архитектуре MQ (например, вот эти статьи: [1], [2], [3]) и определение в Wikipedia — Message queue
Пока давайте посмотрим очень кратко, обзорно, какие системы реализации систем сообщения есть, а, главное, какие из них можно рассматривать в качестве основы для специфика моего проекта. И хотя я думал рассмотреть только РНР реализации, оказалось, что нужно «копать глубже», поэтому мы затронем и системы на других языках, но обладающие возможность взаимодействовать с РНР-приложениями.
Apache ActiveMQ — открытая реализация брокера сообщений (Message Broker) и Enterprise Integration Patterns (если сейчас и очень кратко — расширение для реализации дополнительной обработки согласно правилам). Этот проект, по моему мнению, из всех открытых, самый мощный и развивающийся, недавно вышла версия 5.1. Он реализовывает множество стандартов и обеспечивает все возможности, необходимые для решений уровня Enterprise, входит в стек Java-технологий от Apache. Что меня заинтересовало, так это возможность кросс-языкового обмена сообщениями, а значит — клиенты могут быть реализованы на любом языке. Для платформ Java, C, C++, C# это библиотека OpenWire, реализующая Wire протокол для нативного доступа к MQ, для остальных языков, включая, что нам и интересно, РНР, есть Stomp — реализация библиотек для разных скриптовых языков, которая превращает сообщения в формат JMS. Кстати, если необходимо обеспечить безопасную коммуникацию и передачу сообщений, можно использовать SSL.
MQS (Minimalist Queue Services) — проект, если можно так сказать, с друго конца. Это небольшая система, написанная на Perl, организовывает систему очередей сообщений, используя XML-RPC протокол, сами сообщения могут хранится как в любой базе данных, так и в файлах. К сожалению, по всей видимости, проект заброшен, так как последняя новость на сайте датирована апрелем 2005 года, а текущая версия — 0.0.14.
Spread — еще одна реализация очереди сообщений, на этот раз на С++, и версии есть для различных платформ, включая Win32, Linux, BSD и MacOS. Текущая версия — 4.0. Система распределенная и ориентирована на высокопроизводительные системы, где клиентов и, соответственно, сообщений, очень много. Заявлена поддержка, в последней 4.0 версии, технологии Virtual Synchrony. Что интересно — в поставку сразу включены бинарные версии для нескольких платформ, а также встроенные интерфейсы для некоторых языков — C/C++, Java, Perl, Python, Ruby. Странно, что четвёртого Р — РНР, среди них нет, но существует расширение в PECL, которое реализовывает весь интерфейс Spread API. Текущая версия 2.1 и достаточно новая, значит проект развивается. Существуют и реализации для других языков, в том числе и альтернативы встроенным интерфейсам, поэтому посмотрите на список здесь, там даже для MS Excel есть расширение. Среди интересных проектов — модуль mod_log_spread для Apache, позволяющий собирать логи доступа с нескольких веб-серверов.
RabbitMQ — высокопроизводительная платформа, написанная на Erlang, основанная на Open Telecom Platform, а значит — очень надежная и масштабированная система, часто применяемая в телекоммуникационных приложениях и других подобных системах. Есть интерфейс только для Java и C++. Система поддерживает стандарт AMQP (Open Standard for Messaging Middleware). Система интересная, знать бы только Erlang, хотя что-то мне подсказывает, что проектируя весь серверный модуль на этой платформе, мы получили бы много «плюшек», в частности, на этой же платформе написан самый популярный Jabber-сервер ejabberd, который также можно применять в он-лайн игровых проектах.
Beanstalkd — также интересный проект, созданный в рамках разработки одного из приложений для социальной сети Facebook, которым пользуется около 10 млн человек (приложением, не сетью). Это специализированный сервер для хранения и обработки очередей заданий, использующий хранение данных в памяти для обеспечения скорости, однако в ущерб отказоустойчивости. Этот проект очень похож на уже ранее описанный нами MemcacheQ, да и сами разработчики выражают благодарность создателям memcached за принципы архитектуры и протокол. Система предназначена для создания асинхронной очереди обработчиков пользовательских задач, которые не требуют немедленного ответа, например, отсылки писем, фоновые обработки и т.п. Существуют клиентские API для различных языков, в том числе для Erlang, OCaml, Perl, PHP, Python, Ruby. Для РНР библиотека расположена здесь и пока имеет версию 0.11, сама разработка началась всего пару месяцев назад (судя по регистрации проекта). Детальнее можно почитать отличный обзор: Beanstalk Messaging Queue Сервер написан на С, что обеспечивает высокую скорость работы, однако специфика проекта в плане хранения всех данных в оперативной памяти не подойдет для тех сфер, где остро необходима максимальная отказоустойчивость, пусть даже ценой дополнительного ПО и затрат на хранение данных в базе.
Пока это все. А как же РНР, спросите вы? Описанные решения основаны на сторонних платформах, однако имеют библиотеки для обеспечения коммуникации с РНР-приложениями. Но существуют и нативные, РНР решения такого рода приложений, конечно, не полные аналоги, здесь уже скажется специфика среды РНР, однако достаточные для многих областей применения. О таких решения я расскажу вам в продолжении этого материала.