🦾 IT-Качалка Давида Шекунца 💪
2023-11-06 10:44
4ront
Здесь можно вспомнить и SmallTalk. Язык, в который Алан и заложил свои идеи ООП.
Основными идеями Smalltalk являются:
* Всё - объекты, и всё их взаимодействие — через посылку сообщений;
* Всё доступно для изменения;
* Динамическая типизация
———
Еще задолго до появления Smalltalk Алан Кей сформулировал три фундаментальных принципа объектно-ориентированного программирования (Simula-67):
* Объект - базовая единица объектно-ориентированной системы.
* Объекты могут обладать состоянием.
* Посылка сообщения - единственный способ обмена информацией между объектами.
У нас есть было 2 стула вида коммуникации
Event Driven Architecture (выкинули event и забыли, а с другой стороны кучей читателей прочитали) и RPC (отправили запрос, ждем ответ от 1 читателя) + ясен пень, это все должно работать в кластерном режиме хотябы из 3-х нод
EDA должен нам гарантировать: "если мы выкинули event и увидели, что он попал в очередь, то с другой стороны его рано или поздно смогут прочитать в правильной последовательности нужное кол-во инстансов"
RPC должен гарантировать: "если читателя нет, то мы должны об этом узнать, чтобы сделать retry, если его так и не появлось, то вернуть timeout, а если читатель есть, то в оптимальный промежуток времени получить ответ или вернем timeout"
Заходят в бар RMQ, NATS и Kafka
NATS – message broker, то есть его задача дать возможность подписаться и отправлять сообщения в топики в формате fire-and-forget, при этом он не гарантирует очередность.
Он отлично подходит для RPC (в нем даже есть вшитый модуль), но поскольку он не гарантирует последовательность и что сообщение дойдет до читателя, который еще не успел подняться, мы не можем использовать его для EDA (сразу скажу, JetStreams не рассматриваем)
Kafka – распределенный лог: записываем в конец и читаем с желанного момента (оффсета)
Прекрасно решает вопрос EDA (сложность только в рассчете партишенов и реализации внешних локов на очереди, но об этом ниже) и в целом можно реализовать RPC (он просто будет немного "жирным")
RMQ – это что-то среднее между двумя мирами: fire-and-forget, с гарантированной последовательностью, а распределение и уникальность достигаются параметрами очереди (exclusive, single-active-consumer, durabitlity, etc.) и жанглированием видами exchange + queue
В теории, он хорошо решает вопрос RPC (в нем даже есть встроенный RPC плагин) и, заисключением долговременного хранения сообщений, он даст нам все нужные для EDA характеристики, даже с возможностью выбирать между скоростью (отсутствие репликации) и надежностью (латентная Kafka репликация)
На практике же это гавно работает нормально только при определенных настройках из-за которых он становится херовой альтернативой как NATS, так и Kafka
Мульти-тул = зеро-кволити
Так вот, RMQ очень любит разъебать кластер и не собрать его.
Во-первых, для RMQ абсолютная норма показывать вам, что все в порядке, все очереди и exchange есть, но на деле при попытке записи или потребления ничего происходить не будет ДАЖЕ ОШИБКИ. Почему? Потому что он неправильно синхронизировал свою конфигурацию. Как лечить? Или ручным удалением очередей, или перезагрузкой ноды, или сменой всего кластера (я не шучу, нам приходилось все 3 варианта делать)
Во-вторых, если вы не используете quorum (реплицируемые) очереди или используете любой вид TTL на очередях, то любые проблемы в кластере гарантируют вам или полную дисфункцию этих очередей, или полную дисфункцию кластера.
А если вы используете quorum очереди, то готовьтесь к мощной деградации скорости передачи и обработки сообщений.
То есть, чтобы RMQ работал стабильно, нам придется превратить его в более медленную версию Kafka без персистентного лога.
Из преимуществ остается только его встроенная система управления читателями, НО смехуючек в том, что в итоге, если вы хотите не просто иметь "одного читателя в моменте на очередь", а "по одному читателю в моменте на набор очередей с балансировкой кол-ва очередей к читателям" (а это частый кейс), вам так и так придется самостоятельно реализовывать локи на очереди, как и на Kafka...
Для меня это очередной кейс "швейцарского ножа", который может, но херов во всем
Можно ли использовать RMQ? Если вы будете использовать quorum очереди без частого их создания, вам достаточно fire-and-forget и при этом не хотите разбираться с партишенами, курсорами и распределением в Kafka, то да RMQ будет делать свое дело.
В остальных случаях, при выборе между RMQ и Kafka, лучше выбрать Kafka. С ней гораздо больше проблем вначале, но потом можно хотябы спать по ночам.