Pull to refresh

Comments 16

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

+ если по какой либо причине закончилось место под хранилище, с большой долей вероятности оно будет испорчено

+ Не все написанное выше подходит к quorum очередям

+ В кластерной конфигурации надо очень сильно следить за состоянием кластера - ошибки в репликации или внезапные наплывы данных могут привести к рассинхронизации и, как следствие, не полученным данным

+ Как минимум в старых версиях реббит чувствителен к другой нагрузке на процессоры, при видимой средней загрузке и большом количестве context switch'ей может внезапно обрывать соединения

+ При планируемой нагрузке больше 10к сообщений в секунду стоит выбрать другую технологию

+ Подключение с oauth, проверка ландшафта и прочие улучшения могут существенно снизить производительность

+ При получении данных с concurrency > 1 порядок сообщений на клиенте не гарантирован

+ Стандартная .net библиотека не очень хорошо работает с многопоточной отправкой на большом количестве сообщений и ещё хуже с получением

Спасибо за дополнения.

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

Также я стремился к универсальности и не стал углубляться в специфику разных структур данных. В новых структурах, в том числе в кворумных очередях, некоторые аспекты действительно идут «из коробки» (durability, persistence), однако рекомендации остаются в силе — если не задать эти свойства явно, можно получить не только ошибки несовместимости, но и неожиданные эффекты.

Например, если в виртуальном хосте с default-queue-type: quorum объявить очередь без явного указания типа, то с durable: true получится кворумная очередь, а с durable: false — классическая.

А неперсистентные сообщения, опубликованные в кворумную очередь, могут потеряться при перезапуске брокера после выпадения в DLX, если конечная очередь окажется классической — кролик сохраняет исходный признак персистентности при dead lettering'е.

Поверьте, не критики ради, а дополнения для

Там есть много интересных и пограничных иногда вещей, поэтому пусть это будет в комментариях к хорошой статье

А можно подробнее про пункт "При планируемой нагрузке больше 10к сообщений в секунду стоит выбрать другую технологию"?

Какие проблемы возникают и какую технологию лучше выбрать?

в трех словах - оно не успевает.
https://www.rabbitmq.com/docs/migrate-mcq-to-qq :
A quorum queue can sustain a 30000 message throughput (using 1kb messages), while offering high levels of data safety, and replicating data to all 3 nodes in a cluster. Classic mirrored queues only offer a third of that throughput and provide much lower levels of data safety

Тут, на мой взгляд указана, производительность для единственной очереди на кластере в идеальных условиях, поэтому стоит закладывать производительность с запасом на непредвиденные ситуации

В моём опыте была ситуация, когда росла внутренняя очередь сервиса отправляющего данные или, в случае цепочки очередей, первая очередь переполнялась

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

Хм, а почему kafka сложнее развертывать и под нее сложнее разрабатывать? Скорее уж проще, там гораздо понятнее и логика работы и гарантии, да и настроек поменьше.

Если вы знакомы и с тем и с тем, то вы скорее будете выбирать технологию под конкретную задачу.
Если не знакомы ни с тем, ни с тем, то, условно, кривая обучения для кафки будет sqrt(x), а для RMQ e^x.

Кроме того, на мой взгляд, для кафки нужно очень хорошо подумать сначала и потом делать, реббит в этом смысле прощает немного больше
Плюс ,в энтерпрайзе, особенно если компания посажена на MS и в силу безопасности нацелена на on-prem, есть проблемы с линуксом и людьми которые его поддерживают, в то время как RMQ в дефолтной конфигурации, даже без кластеризации, будет прекрасно работать под win.

Хм, а что прощает кролик такого, что не прощает кафка?

Ну и сейчас уже, подозреваю, не осталось энтерпрайза, где остался win.
Как раз обычно все на linux или вообще в облаках.

если устанавливаете concurrency = 1, то и prefetch_count можно спокойно поставить в 1
или уже использовать kafka у которой очередность сообщений внутри партиции гарантирована "с рождения".

но вообще, про concurrency - это очень ценное замечание!
мало кто читает документацию внимательно, но зато потом удивляются "у меня же очередь! почему у меня сообщения обрабатываются не в том порядке, в котором я их записал?!"

Прошу дать совет: есть очередь из задач, примерно 120млн шт(например id, datetime) и надо их обрабатывать - сходить в другой сервис, получить данные и вернуть ответ в следующую очередь

Положить сразу 120млн сообщений в очередь некрасиво, я сделал доп очередь, в котором лежат сообщения в виде { minId, maxId}, далее обработчик извлекает все id в этом диапазоне и отравляет в следующую очередь

Что я сделал: при обработке minId, maxId проверяю длину следующий очереди, и если она больше чем X, то delay(t sec) , nack ()

В итоге у меня все очереди не превышают заданных лимитов, и я спокоен что ничего не утечет

Нормальный ли этот подход?

Или в корне все криво?

Ваше решение выглядит продуманным и вполне жизнеспособным.

На всякий случай напишу про тонкий момент, связанный с типами очередей. Если сейчас вы используете классические очереди, а со временем решите мигрировать на кворумные, то стоит иметь в виду, что кворумные очереди, в отличие от классических, по умолчанию делают requeue в конец очереди. Привычного поведения можно будет добиться, задав ограничение на количество доставок (delivery-limit).

Я бы предложил разработать решение без очередей, через какое-то другое апи.

Годно но мало. Хотелось бы ещё про HA-(и не только) полиси, кластер, vhost-ы и вот это всё. Ждём продолжения.

У очереди, куда приходят «умершие» сообщения, можно указать время их жизни (message-ttl), а уже упомянутые свойства dead-letter-exchange и dead-letter-routing-key задать так, чтобы сообщения возвращались в исходную очередь. В результате сообщения будут автоматически отправляться на повторную обработку с заданной задержкой.

Это правда очень удобный способ обеспечить повторную обработку через таймаут после ошибки, но как принято в этой схеме обеспечивать порядок обработки сообщений?

То, что попало в DLX, ведь не блокирует обработку того, что продолжает поступать в изначальную очередь. А сквозной порядок через две очереди Rabbit не поддерживает, если не ошибаюсь.

Совершенно верно. Гарантии очерёдности при повторе из DLX, конечно же, теряются.

Sign up to leave a comment.