Гарантированная отправка сообщений
На конференции TeachLeadConf после доклада (видео) мне был задан вопрос про гарантию отправки сообщений в брокер. Если коротко, то вопрос можно сформулировать так: "Как гарантировать отправку сообщений, сохранив их порядок?" Оригинальная формулировка была не столь понятна для меня, поэтому пришлось ответить позже в закрытом чате конференции. Поскол…
считаю, что грешно использовать очереди сообщений в операциях, требующих соблюденя целостности данных. для этого надо использовать трпнзакционную модель, обеспечивающую выполнение правила: всё или ничего
и никак иначе. вы навертели кучу проверочного функционала на все подсистемы и всё равно не добьетесь гарантированного выполнения, только просадите систему по ресурсам, что приведет к нестабильности её работы и снизит общую надежность. очереди сообщений тем и хороши, что легковесны и освобождены от тяжести бремени повышенной надежности. а вы их пихаете во все дыры. потому что "модно-мололежно". резюмируя. для гарантии и надежности используйте транзакционный механизм с подтвкрждением (РСУБД), для скорости, множественной публикации и маршрутизации - очереди.
Здравствуйте!
Спасибо за активность и развернутую обратную связь!
Соглашусь с вами в том моменте, что преждевременное усложнение - это крайне плохо. В идеале хорошо, если агрегат доменной модели целиком хранится в рамках одного хранилища, которое поддерживает транзакции. В остальном есть нюансы, о которых скажу ниже.
В первую очередь хотелось бы сказать, что моя заметка - это ответ на поставленный вопрос. Считайте, что архитектурное решение уже принято без нас с вами, остаётся решить технические детали. Почему было принято такое решение, где компоненты системы должны общаться асинхронно через брокер, да еще с высокими гарантиями доставки, остаётся за рамками поставленного вопроса. Думаю, что на то были веские причины.
Во-вторых, как бы нам с вами не хотелось, но мир движется в сторону распределенных систем и гетерогенному хранению данных. И это факт. Поэтому вопросы согласования данных в распределенных системах оправданно актуальны. В связи с этим инженеры вынуждены разбираться во всех этих нюансах.
В-третьих, в более сложных случаях мы вынуждены идти на декомпозицию системы, организуя ее в виде набора взаимодействующих служб. И иногда нам нужны и гарантии доставки, и порядок событий, и многое другое. Это трудно отрицать, т.к. в противном случае мы скатываемся к примитивизму, где есть только чёрное и белое, правильное и неправильное. Если бы все было так просто. Мы принимаем то или иное архитектурное решение на основании совокупности факторов, не зная которые давать оценочные суждения о удачности решения, как минимум, неправильно. Всегда ли вы можете использовать только ACID-хранилище, в которой помещается весь агрегат? Нет, не всегда, и я это могу сказать с абсолютной уверенностью. Есть предметные области, где важны гарантии согласованности, но документы хранятся в гетерогенном хранилище. Например, медицина. Часть документа хранится в РСУБД, а часть может храниться в BLOB-хранилище. И тут нет возможности использовать только ACID, тут придется использовать либо 2PC (распределенные транзакции), либо механизм повествований (saga).
Наконец, вы сказали, что без ACID нельзя добиться гарантий, согласованности и надёжности. Дело в том, что можно. Шаблон Transactional Outbox (и Inbox), ссылка на который дана в статье, как раз позволяет этого добиться. Конечно, есть нюансы в виде eventual consistency, но они также решаемы.