RabbitMQ и связь между каналом и соединением



The RabbitMQ Java client имеет следующие понятия:





  • Connection - подключение к экземпляру сервера RabbitMQ


  • Channel -???

  • пул потоков потребителя-пул потоков, которые потребляют сообщения от очередей сервера RabbitMQ

  • Queue-структура, которая содержит сообщения в порядке FIFO


Я пытаюсь понять связь, и что еще более важно, ассоциации между ними.




  1. Я все еще не совсем уверен, что a Channel это, кроме того, что это структура, которую вы публикуете и потребляете, и что она создается из открытого соединения. Если бы кто-нибудь мог объяснить мне, что представляет собой "канал", это могло бы помочь прояснить некоторые вещи.

  2. какая связь между каналом и очередью? Может ли один и тот же канал использоваться для связи с кратными очередями, или он должен быть 1:1?

  3. какова связь между очередью и пулом потребителей? Могут ли несколько потребителей быть подписаны на одну и ту же очередь? Может ли один и тот же потребитель использовать несколько очередей? Или это соотношение 1: 1?


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

1123   3  

3 ответов:

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

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

    потокобезопасность канала в Java Client API Guide:

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

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

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

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

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

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

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

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

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

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

TL; DR

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

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

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

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

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

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

Факты Канал

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

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

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

потребитель объект, определенный протоколом AMQP. Это не КАНАЛ и не соединение, а то, что ваше конкретное приложение использует в качестве "почтового ящика" для отбрасывания сообщений.

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

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

Comments

    Ничего не найдено.