RabbitMQ: Введение в AMQP

    Построение больших и сложных систем всегда связано с решением проблем обмена данными между различными их узлами. Дополнительные трудности вносят такие факторы, как требования к отказоустойчивости, географическое разнесение подсистем, наличие узлов, взаимодействующих сразу с несколькими другими. Не всегда удобно использовать пресловутую систему клиент-сервер, да и архитектура точка-точка может оказаться не самым подходящим представлением связей.

    И вот, в один прекрасный день, собрались инженеры с духом, и разработали AMQP — Advanced Message Queuing Protocol. Этот протокол позволяет не задумываться над тем, где находятся получатели сообщения, сколько их, от кого надо ждать сообщение, когда оно будет доставлено получателю. Кроме этого, AMQP снимает с разработчика ещё многие рутинные задачи и позволяет заниматься непосредственной проблемой, а не обслуживанием процесса разработки.

    AMQP имеет три базовых понятия:
    • Обменник (exchange)
    • Очередь (queue)
    • Связь, или маршрут (routing key)

    Обмен сообщениями осуществляется в пределах одного обменника (есть ещё цепное связывание, но об этом в другой раз), в котором определены связи, являющиеся своеобразными маршрутами, по которым идут сообщения, попавшие в этот обменник. Каждый маршрут связывает обменник с одной или несколькими очередями. Программное обеспечение, реализующее описанные действия, называют AMQP-сервером. Узлы, помещающие сообщения в обменники и получающие их из очередей, называются AMQP-клиентами. Другими словами, AMQP-сервер предоставляет шину обмена данными, а AMQP-клиенты используют эту шину для обмена сообщениями между собой.
    Клиенты могут создавать новые обменники (об их типах поговорим позже) и очереди:
    Exchange.Declare <exchange1> TYPE <type>
    Queue.Declare <queue1>
    

    Процесс помещения данных на шину называется публикацией. Когда AMQP-клиент публикует сообщение на шину, он задаёт имя обменника и имя связи:
    Message.Publish <message> TO <exchange1> WITH <route1>
    

    До этого момента, один из клиентов должен осуществить связку, указав имя обменника, очереди и маршрут, соответствующий ей:
    Queue.Bind <queue1> TO <exchange1> WITH <route1>
    

    В результате, сообщение <message> будет доставлено в очередь <queue1>.Но на этом ещё не всё, так как путь сообщения очередью не заканчивается. Один из AMQP-клиентов подписывается на получение сообщений, попавших в заданную очередь:
    Queue.Subscribe <pid> TO <queue>
    

    где <pid> — идентификатор процесса. Здесь и далее работа с AMQP будет описываться с точки зрения программирования на Erlang, в реализациях клиентов на других языках сообщения вычитываются из очереди явной инструкцией, либо вешаются коллбэки и подписки как таковой нет. После подписки на очередь, все сообщения, попавшие в неё, будут пересылаться подписанному процессу. Если на одну очередьподписано несколько процессов, сообщения будут распределяться по подписчикам методом round-robin.

    Для получения ответа, при отправлении запроса в свойствах сообщения заполняется полеReply-To, содержащее, как правило, очередь приватного типа, на которую подписан только отправитель.

    На этом пока всё, в следующий раз постараюсь написать про типы обменников и показать примеры кода, хотя посмотреть их можно уже сейчас вот здесь.

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 15

      +2
      Классная тема, но так мало написали :)
        +1
        Это только начало. Да и ночь на дворе, спать хочется :)
        +1
        Спасибо :) ждем вторую часть
          0
          Интересно было бы услышать про возможность создания аналога Topic'а в JMS (когда каждое сообщение доставляется всем подписчикам). И еще плюсы/минусы этого способа по сравнению с обычным межпроцессным обменом сообщениями в Erlang.
            0
            В AMQP есть тип обменника topic, он позволяет доставлять сообщение по маске маршрута нескольким подписчикам.
            Плюсов/минусов по сравнению с ерланговым IPC нет, так как это разные виды взаимодействия. Заменить одно другим можно в очень небольшом количестве случаев.
            0
            А как нибудь можно это прикрутить чтобы центральный сервер например давал задачи удаленным bash скриптам, а после завершения работы эти скрипты давали обратно результаты (асинхронно). потому как центральный сервер не должен дожидаться ответа, а продолжать раздавать задачи и если ответ получит, то уже тогда выполнять какие-то действия.
              0
              Не вижу никаких препятствий. Вам может помочь библиотека для питона amqplib, как раз под ваши потребности.
              0
              Почему бы не рассматривать систему обмена сообщениями как SOAP сервера, один из которых выполняет функции центра обмена сообщений — то есть для пересылки сообщения от сервера A серверу Б мы посылаем сообщение серверу С с указанием адреса отправителя и получателя? Стандартный отлаженный протокол. Какой плюс в собственном протоколе?
                0
                AMQP более близок к транспортному уровню, поверх него можно и SOAP пустить. Изначальной задачей разработчиков протокола AMQP было получить высокоскоростную и отказоустойчивую среду передачи данных, что и было заложено в спецификации. И формат протокола бинарный именно из-за желания пропускать больше полезного трафика в единицу времени и быстрее обрабатывать служебные данные.
                0
                Вопросы (м.б. у кого-нибудь будут ответы?)
                1. Удобно ли с помощью AMQP-брокеров реализовывать однопроцессные управляемые событиями приложения?
                2. При (1) какие ограничения на архитектуру (объём памяти, конкуренция с другими процессами по ресурсам и т.п., для qpid/c — фрагментация выделения памяти на сообщения в очередях) актуальны?
                3. Можно ли qpid/c прикрутить к одной из библиотек асинхронного ввода/вывода, что бы использовать существующие наработки?
                  0
                  1. Можно, но непонятно, зачем AMQP.
                    0
                    Для взаимодействия с другими процессами с одной стороны, для API-совместимости компонентов с другой стороны и для повышенной лёгкости переконфигурирования ресурсов как следствие предыдущих двух соображений.
                      0
                      Да никто не мешает так делать.
                  0
                  Маленькое дополнение, не знаю виноват ли протокол, или Эрланг, но очередь сообщений в Эрланге не имеет приоритетов, это немного расстраивает во время разработки. В протоколе есть понятие приоритета сообщений?
                    0
                    Ерланговая очередь сообщений действительно не имеет приоритета, но сообщения из неё можно вычитывать, используя сопоставление по шаблону, что может дать примерно тот же результат. В rabbitmq-erlang-client реализован gen_server2, который делает как раз то же самое, т.е. выбирает из мэйлбокса процесса данные с наибольшим приоритетом в первую очередь.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое