2013-08-24 2 views
103

RabbitMQ Java client имеет следующие понятия:RabbitMQ и связь между каналом и связи

  • Connection - соединение с сервером, например RabbitMQ
  • Channel - ???
  • нить
  • Потребитель - бассейн потоков, потребляющих сообщения из RabbitMQ сервера очередей
  • Очереди - это структура, которая содержит сообщения в порядке их поступления

Я пытаюсь понять отношения, и многое другое важно, ассоциации между ними.

  1. Я все еще не совсем уверен, что такое Channel есть, кроме того, что это структура, публиковать и потреблять от, и что она создается из открытого соединения. Если кто-то может объяснить мне, что представляет собой «Канал», это может помочь прояснить некоторые вещи.
  2. Какова связь между каналом и очередью? Может ли тот же канал использоваться для связи с краткими очередями или он должен быть 1: 1?
  3. Какова связь между очередью и пулом потребителей? Можно ли подписывать несколько потребителей на одну и ту же очередь? Можно ли использовать несколько очередей одним и тем же потребителем? Или это соотношение 1: 1?

Заранее благодарим за любую помощь здесь!

ответ

122
  1. Connection представляет собой реальное соединение TCP для брокера сообщений, в то время как Channel это виртуальное соединение (AMPQ соединение) внутри него. Таким образом вы можете использовать столько (виртуальных) соединений, сколько хотите внутри своего приложения, не перегружая брокера TCP-соединениями.

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

    Channel thread-safety in Java Client API Guide:

    экземпляры канала являются безопасными для использования нескольких потоков. Запросы в a Канал сериализуются, и только один поток может выполнять команду на канале за раз. Тем не менее, приложения должны предпочесть с использованием канала на поток вместо совместного использования одного канала через нескольких потоков.

    Не существует прямой связи между Channel и Queue. A Channel используется для отправки команд AMQP брокеру. Это может быть создание очереди или аналогичной, но эти понятия не связаны друг с другом.

  3. Каждый Consumer работает в своей собственной теме, выделенной из пула потребительских потоков. Если несколько потребителей подписываются на одну и ту же очередь, брокер использует циклический доступ для равномерного распределения сообщений между ними. См. Tutorial two: "Work Queues".

    Также можно подключить одинаковые Consumer к нескольким очередям. Вы можете понимать Потребителей как обратные вызовы. Они называются каждый раз, когда сообщение поступает в очередь, к которой привязан Потребитель. В случае клиента Java каждый потребитель имеет метод handleDelivery(...), который представляет собой метод обратного вызова. Что вы обычно делаете, это подкласс DefaultConsumer и переопределить handleDelivery(...). Примечание. Если вы присоедините один и тот же экземпляр пользователя к нескольким очередям, этот метод будет вызываться разными потоками. Поэтому при необходимости позаботьтесь о синхронизации.

+4

Просто для добавления из документации: Обратные вызовы для потребителей отправляются в потоке отдельно от потока, управляемого соединением. Это означает, что потребители могут безопасно вызывать методы блокировки в соединении или канале, такие как queueDeclare, txCommit, basicCancel или basicPublish. У каждого канала есть своя потоковая рассылка. Для наиболее распространенного случая использования одного потребителя на канал это означает, что потребители не задерживают других потребителей. Если у вас есть несколько потребителей на канал, имейте в виду, что долгосрочный потребитель может задержать отправку обратных вызовов другим потребителям на этом канале. – filip

+1

Если вы присоединяете один экземпляр пользователя к нескольким очередям из того же канала, что означает, что обратные вызовы отправляются в тот же поток. В таком случае вам не нужна синхронизация, не так ли? – filip

+0

Могу ли я использовать только одно соединение и использовать пул каналов вместо пула соединений? Будет ли это влиять на пропускную способность публикации сообщений? – qeek

17

Я нашел эту статью, которая объясняет все аспекты модели AMQP, одним из которых является канал. Я нашел, что это очень полезно в округляя моего понимание

https://www.rabbitmq.com/tutorials/amqp-concepts.html

Некоторых приложения требуют несколько подключений к AMQP брокеру. Тем не менее, нежелательно одновременно открывать много соединений TCP, потому что это расходует системные ресурсы и затрудняет настройку брандмауэров. Соединения AMQP 0-9-1 мультиплексируются с каналами, которые можно рассматривать как «легкие соединения, которые используют одно TCP-соединение».

Для приложений, которые используют несколько потоков/процессов для обработки, очень часто открывается новый канал для потока/процесса и не обменивается каналами между ними.

Связь на определенном канале полностью отделена от связи по другому каналу, поэтому каждый метод AMQP также содержит номер канала, который клиенты используют для определения того, к какому каналу относится этот метод (и, следовательно, какой обработчик события необходимо вызвать , например).

5

Полезное концептуальное понимание того, что протокол AMQP делает «под капотом», здесь полезен. Я бы предположил, что документация и API, которые AMQP 0.9.1 выбрал для развертывания, делают это особенно запутанным, поэтому сам вопрос - это тот, с которым приходится бороться много людей.

TL; DR

A соединение это физическое переговоры TCP-сокет с AMQP сервером. У правильно реализованных клиентов будет одно из этих приложений, потокобезопасное, разделяемое между потоками.

A канал - это сеанс одного сеанса связи. В потоке будет один или несколько из этих сеансов. Архитектура AMQP 0.9.1 заключается в том, что они не должны быть разделены между потоками и должны быть закрыты/уничтожены, когда поток, который его создал, завершен. Они также закрываются сервером при возникновении различных нарушений протокола.

A потребитель - это виртуальная конструкция, представляющая наличие «почтового ящика» на определенном канале. Использование потребителя указывает брокеру направить сообщения из определенной очереди в конечную точку этого канала.

Подключение Факты

Во-первых, как уже правильно отметили выход, соединение является объектом, который представляет фактическое соединение TCP к серверу.Соединения указаны на уровне протокола в AMQP, и вся связь с брокером происходит по одному или нескольким соединениям.

  • Поскольку это фактическое TCP-соединение, у него есть IP-адрес и порт #.
  • параметры протокола согласовываются на основе каждого клиента как часть установки соединения (процесс, известный как рукопожатие
  • Он предназначен для долгоживущего;. Есть несколько случаев, когда соединение закрытие является частью конструкции протокола.
  • с точки зрения OSI, он, вероятно, находится где-то около Layer 6
  • Heartbeats можно настроить для контроля за состоянием соединения, так как TCP не содержит ничего, и само по себе, чтобы сделать это.
  • Лучшее чтобы выделенный поток управлял чтением и записью в основной сокет TCP. Большинство, если не все, клиенты RabbitMQ делают это. В этом отношении они, как правило, являются потокобезопасными.
  • Относительно говоря, соединения «дороги», чтобы создать (из-за рукопожатия), но практически говоря, это действительно не имеет значения. Для большинства процессов действительно нужен только один объект соединения. Но вы можете поддерживать соединения в пуле, если вы обнаружите, что вам требуется больше пропускной способности, чем может обеспечить один поток/сокет (маловероятный с использованием современных вычислительных технологий).

канала Факты

Канал это приложение сеанса, который открыт для каждой части вашего приложения, чтобы общаться с RabbitMQ брокером. Он работает через одно соединение и представляет собой сеанс с брокером.

  • Поскольку он представляет собой логическую часть логики приложения, каждый канал обычно существует в своем потоке.
  • Как правило, все каналы, открытые вашим приложением, будут иметь одно соединение (это легкие сеансы, которые работают поверх соединения). Соединения являются потокобезопасными, поэтому все в порядке.
  • Большинство операций AMQP проходят по каналам.
  • С точки зрения уровня OSI, каналы, вероятно, около Layer 7.
  • Каналы предназначены для переходных процессов; часть дизайна AMQP заключается в том, что канал обычно закрыт в ответ на ошибку (например, повторное объявление очереди с разными параметрами перед удалением существующей очереди).
  • Поскольку они временны, каналы не должны объединяться в ваше приложение.
  • Сервер использует целое число для идентификации канала. Когда поток, управляющий соединением, получает пакет для определенного канала, он использует этот номер, чтобы сообщить брокеру, к какому каналу/сеансу принадлежит пакет.
  • Каналы обычно не являются потокобезопасными, так как не имеет смысла делиться ими между потоками. Если у вас есть другой поток, который должен использовать брокера, необходим новый канал.

Потребительские Факты

Потребитель является объектом определяется AMQP протоколом. Это ни канал, ни соединение, а не то, что ваше конкретное приложение использует как «почтовый ящик» для сортировки сообщений.

  • «Создание потребителя» означает, что вы говорите брокеру (используя канал через связь), который вы хотели сообщения, переданные вами по этому каналу. В ответ брокер зарегистрирует, что у вас есть потребитель на канале и начните нажимать на вас сообщения.
  • Каждое сообщение, нажимаемое на соединение, будет ссылаться как на номер номер, так и на потребительский номер . Таким образом, поток управления подключением (в данном случае, в Java API) знает, что делать с сообщением; то поток обработки канала также знает, что делать с сообщением.
  • Потребительская реализация имеет самую широкую вариацию, поскольку она в буквальном смысле относится к конкретным приложениям. В моей реализации я решил отменить задачу каждый раз, когда сообщение прибыло через потребителя; таким образом, у меня был поток, управляющий соединением, поток, управляющий каналом (и по расширению, потребитель), и один или несколько потоков задач для каждого сообщения, доставляемого через пользователя.
  • Закрытие соединения закрывает все каналы на соединении. Закрытие канала закрывает всех потребителей на канале. Также возможно отменить потребителя (без закрытия канала). Существуют различные случаи, когда имеет смысл делать любую из трех вещей.
  • Как правило, реализация потребителя в клиенте AMQP выделяет одному выделенному каналу потребителю, чтобы избежать конфликтов с действиями других потоков или кода (включая публикацию).

С точки зрения того, что вы подразумеваете под пулом потребительских потоков, я подозреваю, что клиент Java делает что-то похожее на то, что я запрограммировал для моего клиента (мой был основан на клиенте .Net, но сильно модифицирован).

Смежные вопросы