Можно ли гарантировать, что уникальные сообщения находятся в очереди rabbitmq?
в основном мои потребители производителей. Мы получаем исходный набор данных и он отправляется в очередь. Потребитель берет товар и обрабатывает его, с этого момента есть 3 возможности:
- данные хороши и получает положить "хорошую" очередь для хранения
- данные плохие и отброшены
- данные не являются хорошими(пока) или плохими (пока), поэтому данные разбиваются на более мелкие части и отправляются обратно в очередь для дальнейшей обработки.
мой проблема заключается в шаге 3, потому что очередь растет очень быстро, сначала возможно, что часть данных разбивается на часть, которая дублируется в очереди, и потребители продолжают ее обрабатывать и попадают в бесконечный цикл.
Я думаю, что способ предотвратить это, чтобы предотвратить дубликаты в очереди. Я не могу сделать это на стороне клиента, потому что в течение часа у меня может быть много ядер, имеющих дело с миллиардами точек данных(для сканирования каждого клиента это перед отправкой слишком сильно замедлит меня). Я думаю, что это нужно сделать на стороне сервера, но, как я уже упоминал, данные довольно большие, и я не знаю, как эффективно обеспечить отсутствие дубликатов.
возможно, я прошу невозможного, но подумал, что попробую. Любые идеи будут высоко оценены.
2 ответов
основная проблема заключается в следующем:
"...its possible that a piece of data is broken down into a part that's
duplicated in the queue and the consumers continue to process it and
end up in a infinite loop."
вы можете сосредоточиться на уникальности вашей очереди, все, что вы хотите, но вопрос выше, где вы должны сосредоточить свои усилия, ИМО. Одним из способов предотвращения бесконечного цикла может быть наличие "посещенного" бита в полезной нагрузке сообщения, который задается потребителями перед повторной очередью разбитого элемента.
другим вариантом было бы вернуть потребителей в специальную очередь, которая обрабатывается немного иначе, чем предотвратите бесконечный цикл. В любом случае, вы должны атаковать проблему, рассматривая ее как основную часть стратегии вашего приложения, а не использовать функцию системы обмена сообщениями, чтобы обойти ее.
Я думаю, даже если вы могли бы исправить проблему не отправки дубликатов в очередь, вы рано или поздно нажмете эту проблему:
из документации RabbitMQ: "восстановление после сбоя: в случае, если клиент отключен от брокера из-за сбоя узла, к которому был подключен клиент, если клиент был клиентом публикации, брокер может принимать и передавать сообщения от клиента без получения клиентом подтверждение для них; и также на стороне потребления возможно, что клиент выдал подтверждения для сообщений и понятия не имеет, были ли эти подтверждения сделаны брокеру и были обработаны до того, как произошел сбой. Короче говоря, вам все равно нужно убедиться, что ваши потребляющие клиенты могут идентифицировать и обрабатывать повторяющиеся сообщения."
в основном, это выглядит так, вы отправляете запрос в rabbitmq, rabbitmq отвечает ACK, но для 1 причина или другое, ваш потребитель или производитель не получает этот ACK. Rabbitmq не может знать, что ack не был получен, и ваш производитель в конечном итоге повторно отправит сообщение, так и не получив ack.
Это боль для обработки повторяющихся сообщений, особенно в приложениях, где обмен сообщениями используется как своего рода RPC, но похоже, что это неизбежно при использовании такого рода архитектуры обмена сообщениями.