
River OSS и Kafka: почему transactional outbox не гарантирует порядок событий агрегата
Меня зовут Василий Миловидов, я системный архитектор в крупной компании. Мы строим обмен между сервисами на событиях: сервис меняет агрегат в PostgreSQL, в той же транзакции кладёт задачу в outbox на River, воркер публикует событие в Kafka с ключом aggregate_id.Разбирая соседнюю задачу, я обнаружил, что эта схема не даёт гарантии, которую мы в неё заложили. Строгого порядка событий одного агрегата в ней нет, и Kafka тут ни при чём: порядок теряется раньше, на своих же воркерах.Статья написана для моей команды, чтобы у всех была одна картина проблемы и один язык для её обсуждения. Если она пригодится кому‑то ещё, тем лучше. Отдельно я старался, чтобы текст был понятен человеку, который только начинает работать с распределёнными системами: каждый механизм я объясняю с точки зрения того, что он делает и от чего защищает.Всё, что касается поведения River, Kafka и PostgreSQL, проверено по документации, ссылки собраны в конце. Там, где утверждение является моим выводом, а не документированным поведением, я это отмечаю отдельно. Читать далее