Заявка теряется не тогда, когда её плохо написали, а тогда, когда её некуда положить. Отправляющая система дошла до получателя, получатель в эту секунду перезагружался, отправитель получил отказ — и дальше всё зависит от одного: есть ли между ними буфер. Если есть, заявка полежит и уедет позже. Если нет, она исчезает, причём молча: у отправителя записана ошибка в лог, у получателя не записано ничего, а у вас нет ни того, ни другого.
Очередь и повторные попытки — два механизма, которые превращают «отправили и надеемся» в «доставим или скажем, что не смогли». В смете подрядчика это две строки, которые вычёркивают первыми, потому что их пользу невозможно показать на демонстрации: на приёмке всё и так работает. Проявляются они через месяц, в первую же аварию.
Ниже — устройство обоих механизмов на бытовой аналогии, лестница пауз между попытками, разбор того, чего повторять нельзя ни при каких условиях, и расчёт потерь на модельном потоке в 1 000 заявок в месяц. Что такое вебхук и почему отправитель вообще может не дождаться ответа, разобрано в опорной статье про API и вебхуки.
Что такое очередь и что происходит без неё
Промежуточное хранилище между двумя системами. Отправитель кладёт сообщение в очередь и сразу получает подтверждение приёма — на этом его работа закончена. Получатель забирает сообщения из очереди со своей скоростью и в своё время. Ключевое свойство: очередь живёт на диске, а не в памяти, и переживает перезапуск сервера.
Бытовая аналогия — приёмная. Без приёмной посетитель приходит к закрытой двери кабинета и уходит: он не оставил заявку, он не записан, никто не знает, что он приходил. С приёмной секретарь принимает папку и выдаёт номерок, даже если кабинет закрыт до трёх часов. Начальник разбирает стопку, когда вернётся, и разбирает её целиком.
Практическая разница видна на четырёх типовых событиях. Все они происходят в любой компании регулярно и ни одно не является аварией.
| Событие | Без очереди | С очередью |
|---|---|---|
| Перезапуск 1С после обновления конфигурации, 12 минут | Всё, что пришло за 12 минут, потеряно | Сообщения ждут, после старта уезжают за секунды |
| Ночное обслуживание базы, 40 минут | Ночные заказы с сайта не доехали, утром их нет | Утром документы на месте, время создания сохранено |
| Пик в день распродажи: 400 заявок за 10 минут | Получатель захлёбывается и отвечает отказом на половину | Очередь принимает всё, отдаёт получателю ровным потоком |
| Обрыв связи с офисом на 3 часа | Заявки уходят в никуда, менеджеры не знают об этом | Очередь растёт, мониторинг сообщает о длине, потерь нет |
Карта связей. Слева узел «Сайт и формы», от него стрелка «новая заявка» к узлу «Приёмник», от приёмника обратная короткая стрелка «подтверждение приёма за 0,2 с». Дальше стрелка «сообщение на диск» к узлу «Очередь». От «Очереди» стрелка к узлу «Обработчик», от него стрелка «документ» к узлу «1С и CRM». От «Обработчика» назад к «Очереди» петля с подписью «повтор: 5 с → 1 мин → 5 мин → 15 мин → 1 ч → 4 ч». От «Очереди» вниз отдельная стрелка «6 попыток исчерпано» к узлу «Карантин», рядом человеческая фигура и подпись «разбирает человек, срок — рабочий день». Сбоку врезка: «Очередь 54 000 ₽, карантин 38 000 ₽». Чертёжный стиль, подписи по-русски.
Лестница повторов: пять секунд, минута, пять минут, час
Повтор без паузы бесполезен и вреден. Если получатель перегружен, три попытки подряд с интервалом в секунду добьют его окончательно. Поэтому паузы нарастают: каждая следующая попытка отстоит от предыдущей дальше, чем прошлая. Рабочая лестница выглядит так.
| Попытка | Пауза перед ней | Прошло с первой отправки | Что обычно чинится к этому моменту |
|---|---|---|---|
| 1 | — | 0 | Ничего, это первая отправка |
| 2 | 5 секунд | 5 секунд | Одиночная сетевая ошибка, потеря пакета |
| 3 | 1 минута | 1 минута 5 секунд | Короткая перегрузка получателя |
| 4 | 5 минут | 6 минут 5 секунд | Перезапуск службы, обновление конфигурации |
| 5 | 15 минут | 21 минута 5 секунд | Перезагрузка сервера, обслуживание базы |
| 6 | 1 час | 1 час 21 минута | Плановое ночное обслуживание |
| 7 | 4 часа | 5 часов 21 минута | Серьёзная авария, к этому моменту уже нужен человек |
Из таблицы следуют два числа, которые стоит проверить в предложении подрядчика. Первое: шесть повторов закрывают окно недоступности в 5 часов 21 минуту — этого достаточно почти для любого планового обслуживания и для большинства аварий. Второе: часовой сбой закрывается уже пятой попыткой, то есть без участия человека и без единой потерянной заявки. Если в предложении написано «три попытки с интервалом 30 секунд», окно защиты — полторы минуты, и оно не покрывает даже перезапуск службы.
Ступенчатая диаграмма из семи ступеней, каждая шире и выше предыдущей. Подписи ступеней снизу: «1 — сразу», «2 — через 5 с», «3 — через 1 мин», «4 — через 5 мин», «5 — через 15 мин», «6 — через 1 ч», «7 — через 4 ч». Над ступенями идёт накопительная линия с подписями «1 мин 5 с», «21 мин 5 с», «1 ч 21 мин», «5 ч 21 мин». Горизонтальными пунктирами отмечены три типовых окна сбоя: «перезапуск службы — 12 минут» пересекает ступень 5, «ночное обслуживание — 40 минут» пересекает ступень 6, «обрыв связи — 3 часа» пересекает ступень 7. Справа врезка: «Три попытки по 30 секунд закрывают 1,5 минуты». Чертёжный стиль, подписи по-русски.
Почему бесконечный повтор опаснее честного отказа
Соблазн понятен: раз повторы спасают заявки, пусть система повторяет, пока не получится. На практике бесконечный повтор создаёт три беды, каждая из которых дороже, чем потеря одного сообщения.
- 1Одно кривое сообщение блокирует всё, что за ним. Заказ с несуществующим артикулом не запишется никогда — ни на десятой попытке, ни на тысячной. Если очередь строго последовательная, за ним встанут все остальные заказы, и обмен встанет целиком из-за одной опечатки в справочнике. Именно поэтому нужен предел попыток и карантин, а не бесконечное упорство.
- 2Повторы съедают лимит чужого API. Если у сервиса лимит 5 000 запросов в сутки, а сотня сообщений повторяется без предела, к обеду квота закончится — и откажут уже нормальным заявкам, которые могли бы пройти. Что бывает при превышении лимитов и как это выглядит со стороны бизнеса, разбираем отдельно в кластере про интеграции.
- 3Лавина при восстановлении. Получатель поднялся — и в него разом влетает всё накопленное плюс все повторы. Практический пример: повторная выгрузка за квартал даёт 4 200 сообщений, а приёмник переваривает 100 в минуту. При выпуске «как есть» он падает снова, теперь уже от вашей же очереди. Правильно — ограничить скорость выпуска: 4 200 сообщений разойдутся за 42 минуты и никого не уронят.
Это короткий тест на зрелость решения. Ответ «повторяем, пока не пройдёт» означает, что первая же ошибка в справочнике остановит обмен целиком, а потом ещё и выжжет лимит чужого API. Правильный ответ звучит так: попытки исчерпаны — сообщение уходит в карантин, приходит оповещение, очередь продолжает работать дальше.
Карантин: полка для того, что не поедет никогда
Карантин — это отдельное хранилище для сообщений, которые не удалось обработать за все попытки. По смыслу это не мусорная корзина, а стол разбора: каждое сообщение здесь означает конкретную заявку конкретного клиента, которая не доехала, и требует решения человека, а не машины.
На модельном потоке в 1 000 заявок в месяц в карантин попадает 3–6 сообщений — как правило, по одним и тем же причинам: артикул, которого нет в справочнике получателя, контрагент без ИНН, статус, для которого не описано правило. Это мало, и именно поэтому карантин бесполезен без регламента: три письма в месяц перестают замечать через две недели.
- 1Кто смотрит
Конкретный сотрудник вашей компании с именем и заместителем на время отпуска, а не «поддержка подрядчика» и не «отдел ИТ». Человек в карантине принимает содержательные решения: этот заказ провести руками, по этому артикулу завести карточку, этого контрагента дозаполнить.
- 2Как часто
Раз в рабочий день, утром, вместе с письмом суточной сверки. Срок разбора — тот же рабочий день: сообщение в карантине означает, что клиент уже чего-то не получил, и каждый день ожидания добавляет к разбору звонок с извинением.
- 3Что должно быть на экране
Причина отказа человеческим языком, а не код ошибки; исходное сообщение целиком; кнопка «отправить заново» после исправления справочника. Без кнопки переотправки карантин превращается в список сожалений: сообщение видно, а сделать с ним ничего нельзя.
- 4Что считается сигналом
Не сам факт попадания в карантин, а его накопление: больше 10 сообщений или рост третьи сутки подряд. Это один из восьми сигналов, по которым видно, что обмен деградирует раньше, чем встанет.
Нарисованный, не скриншотный, абстрактный экран управления очередью. Сверху ряд из четырёх счётчиков: «В очереди — 12», «Самое старое — 4 минуты», «В карантине — 4», «Повторов за сутки — 31». Ниже таблица карантина из четырёх строк с колонками «Заявка», «Причина отказа», «Попыток», «Действие»: «Заявка 1041 — артикул 77-234 не найден в справочнике — 6 — кнопка «Отправить заново»»; «Заявка 1052 — у контрагента не заполнен ИНН — 6 — кнопка»; «Заявка 1060 — нет правила для статуса «Частично собран» — 6 — кнопка»; «Заявка 1063 — артикул 77-234 не найден в справочнике — 6 — кнопка», последняя строка помечена меткой «повтор той же причины». Внизу подпись: «Одна причина дважды — чинить справочник, а не сообщения». Чертёжный стиль без имитации реального продукта, подписи по-русски.
Что нельзя повторять автоматически
Повтор безопасен, пока операция ничего не меняет во внешнем мире. Как только повтор двигает деньги, товар или доходит до клиента, слепое «попробуем ещё раз» превращается из защиты в источник убытка. Четыре типа операций требуют отдельного обращения.
| Операция | Что бывает при слепом повторе | Как делают правильно |
|---|---|---|
| Платёж или списание средств | Второй платёж тому же поставщику, возврат неделями | Перед повтором запрос «есть ли уже операция с этим ключом» и только потом отправка |
| Сообщение клиенту: SMS, письмо, уведомление | Клиент получает шесть одинаковых сообщений и пишет жалобу | Повтор только при явной ошибке доставки, не более одного раза, с ключом сообщения |
| Проведение документа со списанием остатка | Минус на складе, ложный дефицит, сорванная отгрузка | Повтор после проверки, существует ли документ с этим ключом операции |
| Передача в отгрузку и печать этикетки | Вторая коробка едет клиенту за ваш счёт | Операция помечена как однократная: повтор запрещён, сразу карантин и человек |
Общий принцип для всех четырёх строк один: повтор заменяется вопросом «а не сделано ли уже». Задать этот вопрос можно, только если у операции есть ключ — устойчивый идентификатор, по которому получатель отличает повтор от нового задания. Как устроен ключ операции, кто его формирует и почему номер заказа для этого годится не всегда — в статье про задвоенные заказы при обмене.
Сколько теряется без очереди: расчёт на 1 000 заявок
Модельная компания: оптовая торговля, 1 000 заявок в месяц, средний чек 34 000 ₽, конверсия заявки в сделку 22 %, маржа 18 %. Ожидаемая маржа с одной заявки — 34 000 × 22 % × 18 % = 1 346 ₽. Получатель — 1С:УТ — недоступен примерно час в неделю: обновления, перезапуски, обслуживание базы. Это не авария, это нормальная эксплуатация.
Теперь цена защиты. Очередь с сохранением на диск и подтверждением обработки — 54 000 ₽, карантин с ручной переотправкой — 38 000 ₽, вместе 92 000 ₽. Окупаемость: 92 000 ÷ 14 835 = 6,2, то есть на седьмом месяце. Третья родственная строка — повторные попытки и ключ операции за 46 000 ₽ — в этот расчёт не входит намеренно: она окупается отдельно, через отсутствие дублей, и посчитана в соседней статье кластера.
Двухосевой график за 12 месяцев. Ось X — месяцы с первого по двенадцатый, ось Y — рубли от 0 до 180 000. Сплошная линия — накопленные потери без очереди, растёт равномерно по 14 835 ₽ в месяц, к двенадцатому месяцу достигает 178 020 ₽. Горизонтальная штриховая линия на отметке 92 000 ₽ подписана «очередь 54 000 ₽ + карантин 38 000 ₽, разово». Точка пересечения между шестым и седьмым месяцем выделена кружком и подписана «окупаемость, 6,2 месяца». Сбоку врезка: «15 заявок в месяц, 1,5 % потока, 10 из них не возвращаются». Чертёжный стиль, подписи по-русски.
Главное возражение к расчёту звучит так: «наши заявки не теряются». Проверяется оно без подрядчика за один вечер. Возьмите прошлый месяц, посчитайте число заявок в источнике — на сайте, в почтовом ящике, в форме — и число созданных за тот же период документов у получателя. Вычтите законные расхождения: отменённые, тестовые, объединённые. Разница и есть ваш процент потерь. Ниже 0,5 % — можно жить без очереди. Выше 1,5 % — дальше можно не считать.
Что закладывать в смету и как проверить на приёмке
В смете надёжной интеграции очередь и повторы занимают три строки. Общий порядок цен и то, как из них складывается разница между дешёвым и надёжным вариантом, разобраны в материале о стоимости надёжной интеграции; здесь важнее, что именно вы получаете за каждую строку.
| Строка сметы | Цена | Что входит | Как проверить, что сделано |
|---|---|---|---|
| Очередь сообщений | 54 000 ₽ | Хранение на диске, подтверждение обработки, возврат зависшего сообщения по таймауту, ограничение скорости выпуска | Экран со счётчиками: сколько ждёт, какое самое старое |
| Повторные попытки и ключ операции | 46 000 ₽ | Нарастающая пауза, предел попыток, ключ против дублей при повторе | Журнал обмена показывает номер попытки у каждой записи |
| Карантин и ручная переотправка | 38 000 ₽ | Хранилище необработанных сообщений, причина отказа словами, кнопка переотправки, оповещение | Кривая заявка попадает в карантин, следующая за ней проходит |
Приёмка делается заказчиком самостоятельно и занимает полчаса. Требовать её стоит на тестовом контуре, а не на боевой базе — иначе следы проверок останутся в живом учёте.
- 1Остановите получателя на 15 минут и за это время отправьте пять заявок. Включите обратно. Все пять должны появиться у получателя, с исходным временем создания. Ни одна не должна продублироваться.
- 2Отправьте заведомо кривую заявку — с артикулом, которого нет в справочнике. Она обязана уйти в карантин с человекочитаемой причиной, а следующие за ней заявки — пройти без задержки. Если встала вся очередь, предела попыток нет.
- 3Попросите показать экран очереди и карантина и назовите вслух три числа: сколько сообщений ждёт, какое самое старое, сколько в карантине. Если этих чисел негде посмотреть, значит, эксплуатировать обмен будет невозможно — и поддержка превратится в переписку вслепую.
Когда очередь не нужна
Очередь — не обязательный атрибут любой интеграции. Есть четыре ситуации, в которых мы сами предлагаем обойтись без неё и потратить деньги на что-то другое.
- Обмен идёт по расписанию, а не по событию. Если система сама приходит и забирает «всё новое с прошлого раза», буфер не нужен: пропущенный запуск догоняется следующим. Это самый дешёвый способ получить свойство «не теряем», и подробно он разобран в статье про обмен по расписанию и по событию.
- Меньше 150 операций в месяц. Очередь и карантин стоят 92 000 ₽ независимо от объёма. При потоке в 100 заявок потери от недоступности — одна-две заявки в месяц, и разбирать их руками честно дешевле, чем строить контур.
- Обе системы ваши и стоят в одной сети. Недоступность здесь измеряется минутами в месяц, а перезапуски вы планируете сами и можете просто останавливать обмен на это время. Очередь тут решает проблему, которой почти нет.
- Данные не критичны и восстанавливаются пересчётом. Обновление остатков, синхронизация цен, выгрузка в аналитику: если следующий запуск всё равно перезапишет состояние целиком, потеря одного сообщения не значит ничего. Буфер нужен там, где сообщение уникально — заявка, заказ, оплата, — а не там, где оно очередной снимок.
И вывод, который стоит держать в голове при разговоре о цене. Очередь не ускоряет обмен, не добавляет функций и ничего не показывает на демонстрации — она покупает единственное свойство: сбой на той стороне перестаёт быть вашей потерей. Стоит это свойство 92 000 ₽ разово и окупается на седьмом месяце, если ваш получатель недоступен хотя бы час в неделю. А недоступен он бывает у всех: обновления, обслуживание базы и перезапуски — это не аварии, это график.
Интеграция без очереди работает ровно до первого планового обслуживания на той стороне.
