2014-11-21 4 views
4

При использовании RabbitMQ в качестве Message Broker у меня есть сценарий, когда несколько параллельных пользователей извлекают сообщения из очереди с помощью метода basic.get AMQP и используют явное подтверждение для удаления сообщения из очереди , Предполагая следующую настройкуAMQP basic.get одновременных потребителей, вытаскивающих из очереди

Q имеет сообщения M1, M2, M3 и имеет потребителей C1, C2 и C3 (каждый из которых имеет свое собственное соединение и канал), подключенные к нему.

  1. Как осуществляется параллелизм в методе basic.get? Является ли вызов метода basic.get синхронизированным для одновременной обработки параллельных пользователей с использованием собственного соединения и канала? C1, C2 и C3 вызывают вызов basic.get для получения сообщения одновременно (предположим, что сервер одновременно принимает все 3 запроса).

  2. C1 запрашивает сообщение с использованием basic.get и получает M1. Когда C2 запрашивает сообщение, так как он использует другое соединение, он снова получает M1?

  3. Как потребители могут отправлять сообщения пакетами предопределенного размера?

+1

Непонятно, о чем вы спрашиваете. – pinepain

+0

Второй момент - НЕТ. Другие моменты, которые я не понимаю! Что вы подразумеваете под «синхронизированными для обработки параллельных потребителей»! RMQ - это система FIFO, поэтому вы помещаете 3 сообщения, а C1 получаете первый, C2 - секунды и т. Д. Предполагая, что вы используете prefetch = 1. – Gabriele

+0

Помог ли мой ответ ниже? Если да, отметьте это как ответ. Если нет, то как я могу разработать? – theMayer

ответ

-1

Для этого сценария не требуется особой конфигурации. Каждый клиент будет атомарно извлекать и получать одно сообщение из очереди, как вам хотелось бы.

+0

Итак, RabbitMQ обрабатывает часть синхронизации? Выполняет ли она некоторую блокировку в запросе basic.get? –

+0

Перефразируя мой вопрос: как синхронизируется синхронизация на basic.get? Есть ли блокировка в запросе basic.get? –

1

Возможно, вы захотите прочитать RabbitMQ Api guide и introduction to Amqp.

Прежде всего, избегайте использования сообщений, используя basicGet у ваших потребителей. Скорее используйте пользовательский интерфейс basicConsume. Это позволяет RabbitMq нажимать вам сообщения по мере их поступления в очередь. Все остальное - талия ресурсов здесь, поскольку это сводится к оживленному опросу.

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

Параллелизм - это не проблема, вот для чего вы используете очередь! При наличии нескольких потребителей в одной очереди сообщение всегда будет доставлено только одному потребителю (до тех пор, пока сообщение ACKed). В противном случае вам понадобятся частные очереди для каждого пользователя и соответственно направьте свои сообщения.

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

+0

Существуют законные основания использовать метод pull для метода push для извлечения сообщений. – theMayer

+0

Несомненно, есть веские причины для метода вытаскивания! Я бы не стал считать это типичным вариантом использования. – Moritz

+0

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

7

Ваши вопросы действительно попадают в суть теории очередей и процессов, поэтому я отвечу с этой точки зрения (RabbitMQ на самом деле является общим брокером сообщений в отношении моих ответов, поскольку это относится к любому брокеру сообщений).

Как осуществляется параллелизм в методе basic.get? Является ли вызов метода basic.get синхронизированным для обработки параллельных потребителей каждый с использованием собственного соединения и канала? C1, C2 и C3 вызывают вызов basic.get для получения сообщения одновременно (предположим, что сервер принимает все 3 запроса одновременно).

Ответ 1: RabbitMQ предназначен, чтобы быть надежным брокер сообщений. Он содержит внутренние процессы и элементы управления, чтобы гарантировать, что одно и то же сообщение не будет передаваться несколько раз различным потребителям. Теперь, из-за непрактичности тестирования сценария, который вы описываете, работает ли он отлично? Кто знает. Вот почему правильно разработанные приложения, использующие архитектуру на основе сообщений, будут использовать идемпотентные транзакции, так что если одна и та же транзакция обрабатывается несколько раз, результат будет таким же, как если бы транзакция была обработана один раз. Takeaway: спроектируйте ваше приложение так, чтобы ответ на этот вопрос был неважным.

C1 запрашивает сообщение с использованием basic.get и получает M1. Когда C2 запрашивает сообщение , так как он использует другое соединение, он снова получает M1 ?

Ответ 2: Нет С учетом предположений моего предыдущего ответа, RabbitMQ брокер не будет выполнять то же самое сообщение обратно, как только оно было доставлено. В зависимости от настроек канала и очереди сообщение может быть автоматически подтверждено при доставке и никогда не будет повторно отправлено. Другие настройки будут автоматически выдавать запрос сообщения «смерть» обрабатывающего потока/канала или отрицательное подтверждение из вашего потока обработки. Это важная функциональность, поскольку сообщение «яд» может неоднократно наносить ущерб вашему приложению, если оно может обслуживаться несколькими потребителями. Takeaway: вы можете смело полагаться на это предположение при разработке своего приложения.

Как потребители могут отправлять сообщения пакетами предопределенного размера?

Ответ: Они не могут, и не имеет смысла для них. В любой системе очередей основное предположение состоит в том, что элементы удаляются из очереди в одном файле. Попытки нарушить это предположение приводят к непредсказуемому поведению; кроме того, односекционный поток обычно является наиболее эффективным методом обработки. Однако в реальном мире есть случаи, когда размер партии> 1 необходим. В таких случаях имеет смысл загружать пакет в его собственное единственное сообщение, поэтому для этого может потребоваться отдельный поток обработки, который вытаскивает сообщения из очереди и объединяет их вместе или сначала помещает их в пакеты. Имейте в виду, что, когда у вас есть несколько потребителей, нет возможности гарантировать, что отдельные сообщения будут обработаны по порядку. Takeaway: Следует избегать дозирования, если это возможно, но там, где это невозможно, вы можете не предполагать, что партии будут содержать отдельные сообщения в любом конкретном порядке.

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