Webhook не гарантирует порядок доставки, если поставщик явно этого не обещает. Повторы, разные очереди и сетевые задержки могут привести к тому, что delete будет обработан раньше create.

Не применяйте событие сразу к бизнес-таблице. Сначала сохраните его в inbox по уникальному event_id, затем определите версию объекта и допустимый переход состояния.

Что сделать в первую очередь

  • Сохраните исходные event_id, object_id и occurred_at.
  • Проверьте документацию поставщика по порядку и повторам.
  • Остановите только опасный обработчик, продолжая принимать события в inbox.
  • Определите ожидаемое финальное состояние объекта.

Почему возникает проблема

Порядок меняется из-за независимых worker, повторов с backoff и неодинакового времени доставки.

  • Create временно получил ошибку и ушёл на повтор.
  • Delete обработал другой worker быстрее.
  • События из разных partition не имеют общего порядка.
  • Приложение сортирует по времени получения.
  • Часы систем расходятся, а occurred_at ненадёжен.

Пошаговая диагностика

  • Постройте timeline по event_id и журналу приёма.
  • Сравните occurred_at, received_at и версию объекта.
  • Проверьте уникальность event_id.
  • Воспроизведите обратный порядок на тестовом наборе.
  • Проверьте текущее состояние объекта через API источника.

Как исправить

Обработчик должен принимать любое допустимое событие повторно и приходить к одному конечному состоянию.

  • Создайте inbox с уникальным event_id.
  • Используйте версию или sequence объекта, если источник её предоставляет.
  • Храните tombstone для удаления до прихода create.
  • Применяйте переходы через явную state machine.
  • Добавьте reconciliation с источником для спорных случаев.

Как проверить результат

  • Перестановка событий даёт правильный финальный статус.
  • Повтор event_id ничего не дублирует.
  • Неизвестное событие остаётся для разбора, а не теряется.
  • Reconciliation исправляет пропущенную последовательность.

Как не допустить повторения

  • Тестируйте повторы и случайный порядок.
  • Не отвечайте 500 после успешного сохранения в inbox.
  • Мониторьте возраст необработанных событий.
  • Версионируйте схему payload.

Чего не стоит делать

  • Не полагайтесь только на timestamp.
  • Не удаляйте событие после первой ошибки.
  • Не создавайте объект заново после delete без проверки версии.

Что подготовить для диагностики

  • Примеры payload в изменённом порядке.
  • Документация webhook источника.
  • Журнал приёма и обработки.
  • Текущая модель состояния объекта.

Частые вопросы

Достаточно ли сортировать события по времени?

Нет. Время может совпадать или расходиться, а позднее доставленное событие может иметь более ранний timestamp.

Что такое tombstone?

Это минимальная запись о том, что объект удалён; она не позволяет запоздалому create ошибочно восстановить его.

Когда стоит обратиться за помощью

Если потеря порядка уже создаёт дубли и неверные статусы, нужно проверить данные источника, inbox и переходы состояния вместе.

Итог

Webhook следует проектировать как поток с повторами и нарушенным порядком. Я могу внедрить inbox, идемпотентность и reconciliation, чтобы события сходились к правильному результату.