Полезное концептуальное понимание того, что протокол 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, но сильно модифицирован).
Просто для добавления из документации: Обратные вызовы для потребителей отправляются в потоке отдельно от потока, управляемого соединением. Это означает, что потребители могут безопасно вызывать методы блокировки в соединении или канале, такие как queueDeclare, txCommit, basicCancel или basicPublish. У каждого канала есть своя потоковая рассылка. Для наиболее распространенного случая использования одного потребителя на канал это означает, что потребители не задерживают других потребителей. Если у вас есть несколько потребителей на канал, имейте в виду, что долгосрочный потребитель может задержать отправку обратных вызовов другим потребителям на этом канале. – filip
Если вы присоединяете один экземпляр пользователя к нескольким очередям из того же канала, что означает, что обратные вызовы отправляются в тот же поток. В таком случае вам не нужна синхронизация, не так ли? – filip
Могу ли я использовать только одно соединение и использовать пул каналов вместо пула соединений? Будет ли это влиять на пропускную способность публикации сообщений? – qeek