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, чтобы события сходились к правильному результату.