Паттерны интеграции с ERP, которые не ломаются при нагрузке
ERP-интеграции выглядят просто на схеме: система A говорит с системой B. Проблемы начинаются, когда одна из сторон тормозит, падает или накрывается волной трафика. Мы наблюдали, как 10-минутное окно обслуживания ERP валит обработку заказов на два часа. Вот что реально ломается и как построить что-то, что держит удар.
Синхронная и event-driven интеграция: первая создаёт жёсткую связность и общие точки отказа; вторая даёт изоляцию и возможности восстановления.
Почему синхронные интеграции ломаются
Синхронная интеграция понятна: что-то меняется в системе A — вызываешь систему B. Никакого брокера, никаких очередей, никаких лишних движущихся частей. Мы понимаем, почему команды идут именно этим путём.
Загвоздка в том, что обе системы становятся жёстко связанными. Если ERP тормозит во время всплеска трафика, магазин либо ждёт (запросы копятся), либо падает с ошибками (ошибки долетают до пользователей). Если в API заказов магазина сбой — ERP не может обрабатывать. Оба падают вместе.
При малых объёмах заказов это зачастую нормально. Дайте нагрузку — флеш-сейл, Black Friday, массовый импорт каталога параллельно с реальным трафиком — и режимы отказа складываются. Мы видели, как 10-минутное техническое окно ERP породило 400 записей с ошибками и два часа ручной сверки. Это не случайность — это то, что синхронная связность делает под давлением.
Паттерн с очередью сообщений
Поставьте между ними брокер сообщений — RabbitMQ или Kafka. К ним мы обращаемся чаще всего в commerce-стеках, в зависимости от требований к пропускной способности и того, что команда уже знает.
Схема: заказ оформлен в магазине → опубликован как сообщение → ERP-потребитель читает и обрабатывает в своём темпе. Если ERP падает — сообщения копятся в очереди и стекают, когда он вернётся. Ни один заказ не потерян, ни одна ошибка не долетела до пользователя. Магазин вообще не знает, что ERP был недоступен.
То же самое в обратную сторону для инвентаря: ERP публикует событие об изменении остатка, магазин потребляет асинхронно. Несколько секунд задержки в обновлении остатков — нормально в большинстве случаев. Полный сбой синхронизации, который оставляет вас с пересортицей — нет. Очередь даёт буфер, чтобы поглотить всплески и отказы без потери данных.
Ключевые решения при проектировании
Идемпотентность
Доставка «хотя бы один раз» — стандарт для очередей сообщений: при сбоях сообщения могут быть доставлены более одного раза. Ваши потребители должны быть идемпотентными: обработка одного и того же сообщения дважды должна давать тот же результат, что и однократная.
Для создания заказа: проверяйте, существует ли заказ с данным внешним ID, прежде чем создавать его. Для обновления остатков: применяйте абсолютное значение (stock = N), а не дельту (stock += N), чтобы дублирующие сообщения не портили инвентарь.
Очереди мёртвых писем
Часть сообщений не обработается — плохие данные из ERP, таймаут downstream, несовпадение схемы, которое вы не учли. Настройте DLQ: упавшие сообщения после N попыток попадают туда, где их видно, а не просто исчезают. И реально мониторьте его. DLQ на нуле — признак здоровья. DLQ, который растёт в три часа ночи — инцидент в замедленном воспроизведении.
Версионирование схем
ERP-системы обновляются. Структура объекта заказа меняется. Если ваш потребитель хардкодит старые имена полей — он ломается тихо или громко, но в обоих случаях у вас проблема. Включайте поле версии в сообщения. Новые поля добавляйте как необязательные. Обязательные никогда не удаляйте без окна миграции, в котором поддерживаются обе версии. Это скучнее, чем архитектура очереди, но именно здесь интеграции разваливаются на второй год.
Здоровая интеграция: глубина очереди остаётся близкой к нулю при нормальной работе, счётчик DLQ — на 0. Мониторинг обоих в одном дашборде упрощает обнаружение инцидентов.
Что мониторить
Как минимум, наблюдаемость интеграции должна включать:
- Глубину очереди со временем по топикам (растущая очередь указывает на лаг потребителя)
- Лаг потребителя (разница между последним сообщением и последним обработанным)
- Количество сообщений в DLQ и скорость роста
- Время обработки по типу сообщения (выявляйте медленных потребителей до того, как они создадут бэклоги)
- Частоту ошибок и классификацию (временные vs постоянные)
Подключите это к системе алертов. Глубина очереди уверенно растёт 15 минут — кто-то должен получить уведомление. Новые сообщения в DLQ — автоматически создавать тикет. Не надейтесь, что кто-то вспомнит проверить дашборд.
Когда использовать вебхуки вместо очереди
Очереди сообщений добавляют инфраструктурную сложность. Для интеграций с небольшим объёмом и высокими требованиями к надёжности с обеих сторон вебхуки с логикой повторных попыток и заданием сверки (ночная проверка состояний между системами) могут быть проще и вполне достаточны.
Наш честный взгляд: если вы обрабатываете больше ~5 000 событий в час, или у любой из систем бывают плановые окна обслуживания или аптайм ниже 99,9% — идите с очередью. Ниже этого — зависит от операционного комфорта вашей команды и готовности терпеть крайние случаи. Универсального ответа здесь нет.
Следующий шаг
Работаете над сложной commerce-системой?
Мы помогаем инженерным командам проектировать, строить и масштабировать высоконагруженные платформы — с чётким процессом и предсказуемыми сроками.
Поговорим