tgoop.com/java_fillthegaps/537
Create:
Last Update:
Last Update:
Postgres и Kafka, часть 1
Возвращаюсь к ведению канала, и на этой неделе вас ждут 2 огненных поста🔥🔥 о взаимодействии Postgres и Kafka.
Эта пара безумно популярна на большинстве проектов👯♀️ База хранит данные, кафка отвечает за коммуникации между сервисами. Сегодня разберу одну проблему в их отношениях и расскажу вариант решения. А в следующем посте обсудим ещё 2 способа.
Рассмотрим проблему на простом примере.
Пользователь создал заказ, сервис принял запрос. Сервис добавил заказ в базу, и хочет рассказать другим сервисам о новом заказе. Что-то вроде такого:
public Order saveOrder(…) {Другие сервисы, подписанные на orders, получат сообщение и что-то сделают. Посчитают скидки, обновят статистику, запишут заказ в свою БД и тд.
Order saved = orderRepo.save(…);
kafkaTemplate.send("orders",new OrderCreated(…));
}
В чём проблема?
Мы обращаемся к двум отдельным компонентам — базе данных и брокеру сообщений. Каждый из них в любой момент может отвалиться, например, пропадёт связь по сети. В зависимости от порядка строк в saveOrder возможны 2 негативных исхода:
😢 запись в базу сделали, сообщение не отправили
😢 отправили сообщение, но запись в БД не прошла
Получим несоответствие. Поэтому иногда хочется, чтобы события выполнились атомарно: либо оба успешно завершаются, либо ни одно из них.
Большинство разработчиков нетерпеливо скажут: "Что тут думать, нужен transaction outbox!!1". Но если спросить 10 человек, что они под этим понимают, получится 10 разных ответов.
В лучших традициях канала обсудим всё простыми словами:) Очень грубо все решения можно назвать так:
1️⃣ Убираем кафку
2️⃣ Убираем БД
3️⃣ Добавляем координатор
Сегодня рассмотрим первый вариант, в следующем посте — остальные два.
Вариант 1: убираем кафку
У Postgres есть механизм notify/listen, который отправляет уведомления заинтересованным лицам. И вместо отправки сообщений через кафку мы возьмём механизм подписки внутри БД.
База становится единственным компонентом и выполняет оба действия (сохранить в таблицу, уведомить заинтересованных) в одной транзакции.
Чтобы не решать проблемы с координацией двух компонентов, мы переложили всю работу на один.
✅ Образцовая транзакция: атомарность и доставка exactly once
✅ Минимальная задержка между сохранением в базу и уведомлением
❌ Ограниченная функциональность уведомлений
❌ Размытие ответственности — часть уведомлений делает Kafka, часть — Postgres
❌ Увеличение нагрузки на БД
Последний пункт — главный ограничитель, поэтому подход "база делает всё" не очень популярен.
Реализация
Можно взять spring-integration-jdbc и для отправки сообщений, и для получения уведомлений. Документация максимально скудная, дополнительные детали есть в этой статье (под VPN)
В следующем посте обсудим ещё 2 варианта🔥
BY Java: fill the gaps
Share with your friend now:
tgoop.com/java_fillthegaps/537