Заказ в базе есть, а событие об оплате не получил никто
Обработчик оплаты устроен так: транзакция в PostgreSQL коммитится, затем сразу отправляется событие в Kafka:
await session.commit()
await producer.send("payments", event)
Периодически под удаляют при выкатке или брокер недоступен доли секунды. В результате часть оплат есть в базе, но событий по ним нет: сервисы-потребители расходятся с состоянием базы, а расхождение обнаруживают через дни по жалобам.
Какое решение убирает потерю событий?
- Отправлять событие до коммита — тогда оно точно уйдёт в брокер и не потеряется
- Обернуть отправку в повтор с тремя попытками и растущей паузой — этого достаточно
- Писать событие в таблицу outbox в одной транзакции с данными, публиковать отдельным процессом
- Включить подтверждение записи всеми репликами брокера — при таком режиме потерь не будет
