Заявка теряется не тогда, когда её плохо написали, а тогда, когда её некуда положить. Отправляющая система дошла до получателя, получатель в эту секунду перезагружался, отправитель получил отказ — и дальше всё зависит от одного: есть ли между ними буфер. Если есть, заявка полежит и уедет позже. Если нет, она исчезает, причём молча: у отправителя записана ошибка в лог, у получателя не записано ничего, а у вас нет ни того, ни другого.

Очередь и повторные попытки — два механизма, которые превращают «отправили и надеемся» в «доставим или скажем, что не смогли». В смете подрядчика это две строки, которые вычёркивают первыми, потому что их пользу невозможно показать на демонстрации: на приёмке всё и так работает. Проявляются они через месяц, в первую же аварию.

Ниже — устройство обоих механизмов на бытовой аналогии, лестница пауз между попытками, разбор того, чего повторять нельзя ни при каких условиях, и расчёт потерь на модельном потоке в 1 000 заявок в месяц. Что такое вебхук и почему отправитель вообще может не дождаться ответа, разобрано в опорной статье про API и вебхуки.

Что такое очередь и что происходит без неё

Что это значитОчередь сообщений

Промежуточное хранилище между двумя системами. Отправитель кладёт сообщение в очередь и сразу получает подтверждение приёма — на этом его работа закончена. Получатель забирает сообщения из очереди со своей скоростью и в своё время. Ключевое свойство: очередь живёт на диске, а не в памяти, и переживает перезапуск сервера.

Бытовая аналогия — приёмная. Без приёмной посетитель приходит к закрытой двери кабинета и уходит: он не оставил заявку, он не записан, никто не знает, что он приходил. С приёмной секретарь принимает папку и выдаёт номерок, даже если кабинет закрыт до трёх часов. Начальник разбирает стопку, когда вернётся, и разбирает её целиком.

Практическая разница видна на четырёх типовых событиях. Все они происходят в любой компании регулярно и ни одно не является аварией.

СобытиеБез очередиС очередью
Перезапуск 1С после обновления конфигурации, 12 минутВсё, что пришло за 12 минут, потеряноСообщения ждут, после старта уезжают за секунды
Ночное обслуживание базы, 40 минутНочные заказы с сайта не доехали, утром их нетУтром документы на месте, время создания сохранено
Пик в день распродажи: 400 заявок за 10 минутПолучатель захлёбывается и отвечает отказом на половинуОчередь принимает всё, отдаёт получателю ровным потоком
Обрыв связи с офисом на 3 часаЗаявки уходят в никуда, менеджеры не знают об этомОчередь растёт, мониторинг сообщает о длине, потерь нет
карта связейocheredi-i-povtornye-popytki--01
Карта пути заявки: приёмник, очередь, обработчик, ветки повтора и карантина, учётная система

Карта связей. Слева узел «Сайт и формы», от него стрелка «новая заявка» к узлу «Приёмник», от приёмника обратная короткая стрелка «подтверждение приёма за 0,2 с». Дальше стрелка «сообщение на диск» к узлу «Очередь». От «Очереди» стрелка к узлу «Обработчик», от него стрелка «документ» к узлу «1С и CRM». От «Обработчика» назад к «Очереди» петля с подписью «повтор: 5 с → 1 мин → 5 мин → 15 мин → 1 ч → 4 ч». От «Очереди» вниз отдельная стрелка «6 попыток исчерпано» к узлу «Карантин», рядом человеческая фигура и подпись «разбирает человек, срок — рабочий день». Сбоку врезка: «Очередь 54 000 ₽, карантин 38 000 ₽». Чертёжный стиль, подписи по-русски.

Заявка не идёт из сайта в учёт напрямую — между ними четыре узла, и три из них про сбои

Лестница повторов: пять секунд, минута, пять минут, час

Повтор без паузы бесполезен и вреден. Если получатель перегружен, три попытки подряд с интервалом в секунду добьют его окончательно. Поэтому паузы нарастают: каждая следующая попытка отстоит от предыдущей дальше, чем прошлая. Рабочая лестница выглядит так.

ПопыткаПауза перед нейПрошло с первой отправкиЧто обычно чинится к этому моменту
10Ничего, это первая отправка
25 секунд5 секундОдиночная сетевая ошибка, потеря пакета
31 минута1 минута 5 секундКороткая перегрузка получателя
45 минут6 минут 5 секундПерезапуск службы, обновление конфигурации
515 минут21 минута 5 секундПерезагрузка сервера, обслуживание базы
61 час1 час 21 минутаПлановое ночное обслуживание
74 часа5 часов 21 минутаСерьёзная авария, к этому моменту уже нужен человек

Из таблицы следуют два числа, которые стоит проверить в предложении подрядчика. Первое: шесть повторов закрывают окно недоступности в 5 часов 21 минуту — этого достаточно почти для любого планового обслуживания и для большинства аварий. Второе: часовой сбой закрывается уже пятой попыткой, то есть без участия человека и без единой потерянной заявки. Если в предложении написано «три попытки с интервалом 30 секунд», окно защиты — полторы минуты, и оно не покрывает даже перезапуск службы.

графикocheredi-i-povtornye-popytki--02
Лестница из семи попыток: паузы 5 секунд, 1, 5, 15 минут, 1 и 4 часа, суммарное окно 5 ч 21 мин

Ступенчатая диаграмма из семи ступеней, каждая шире и выше предыдущей. Подписи ступеней снизу: «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. 1Одно кривое сообщение блокирует всё, что за ним. Заказ с несуществующим артикулом не запишется никогда — ни на десятой попытке, ни на тысячной. Если очередь строго последовательная, за ним встанут все остальные заказы, и обмен встанет целиком из-за одной опечатки в справочнике. Именно поэтому нужен предел попыток и карантин, а не бесконечное упорство.
  2. 2Повторы съедают лимит чужого API. Если у сервиса лимит 5 000 запросов в сутки, а сотня сообщений повторяется без предела, к обеду квота закончится — и откажут уже нормальным заявкам, которые могли бы пройти. Что бывает при превышении лимитов и как это выглядит со стороны бизнеса, разбираем отдельно в кластере про интеграции.
  3. 3Лавина при восстановлении. Получатель поднялся — и в него разом влетает всё накопленное плюс все повторы. Практический пример: повторная выгрузка за квартал даёт 4 200 сообщений, а приёмник переваривает 100 в минуту. При выпуске «как есть» он падает снова, теперь уже от вашей же очереди. Правильно — ограничить скорость выпуска: 4 200 сообщений разойдутся за 42 минуты и никого не уронят.
Спросите, что происходит на седьмой попытке

Это короткий тест на зрелость решения. Ответ «повторяем, пока не пройдёт» означает, что первая же ошибка в справочнике остановит обмен целиком, а потом ещё и выжжет лимит чужого API. Правильный ответ звучит так: попытки исчерпаны — сообщение уходит в карантин, приходит оповещение, очередь продолжает работать дальше.

Карантин: полка для того, что не поедет никогда

Карантин — это отдельное хранилище для сообщений, которые не удалось обработать за все попытки. По смыслу это не мусорная корзина, а стол разбора: каждое сообщение здесь означает конкретную заявку конкретного клиента, которая не доехала, и требует решения человека, а не машины.

На модельном потоке в 1 000 заявок в месяц в карантин попадает 3–6 сообщений — как правило, по одним и тем же причинам: артикул, которого нет в справочнике получателя, контрагент без ИНН, статус, для которого не описано правило. Это мало, и именно поэтому карантин бесполезен без регламента: три письма в месяц перестают замечать через две недели.

  1. 1
    Кто смотрит

    Конкретный сотрудник вашей компании с именем и заместителем на время отпуска, а не «поддержка подрядчика» и не «отдел ИТ». Человек в карантине принимает содержательные решения: этот заказ провести руками, по этому артикулу завести карточку, этого контрагента дозаполнить.

  2. 2
    Как часто

    Раз в рабочий день, утром, вместе с письмом суточной сверки. Срок разбора — тот же рабочий день: сообщение в карантине означает, что клиент уже чего-то не получил, и каждый день ожидания добавляет к разбору звонок с извинением.

  3. 3
    Что должно быть на экране

    Причина отказа человеческим языком, а не код ошибки; исходное сообщение целиком; кнопка «отправить заново» после исправления справочника. Без кнопки переотправки карантин превращается в список сожалений: сообщение видно, а сделать с ним ничего нельзя.

  4. 4
    Что считается сигналом

    Не сам факт попадания в карантин, а его накопление: больше 10 сообщений или рост третьи сутки подряд. Это один из восьми сигналов, по которым видно, что обмен деградирует раньше, чем встанет.

разбор экранаocheredi-i-povtornye-popytki--03
Абстрактный экран очереди и карантина: счётчики ожидания, причины отказов, кнопка переотправки

Нарисованный, не скриншотный, абстрактный экран управления очередью. Сверху ряд из четырёх счётчиков: «В очереди — 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С:УТ — недоступен примерно час в неделю: обновления, перезапуски, обслуживание базы. Это не авария, это нормальная эксплуатация.

Потери без очереди: 1 000 заявок в месяц, час недоступности в неделю
Рабочий фонд приёма заявок: 22 дня × 12 часов264 часа
Заявок в час1 000 ÷ 264 = 3,8
Недоступность получателя за месяц4 часа
Заявок пришлось на окна недоступности4 × 3,8 = 15
Доля от месячного потока1,5 %
Возвращаются сами: клиент пишет повторно, примерно треть5 заявок
Потеряны безвозвратно10 × 1 346 = 13 460 ₽/мес
Разбор пяти повторных обращений: 15 минут × 1 100 ₽/час5 × 275 = 1 375 ₽/мес
Итого14 835 ₽ в месяц при 1,5 % потерь потока — и ни одна из этих заявок нигде не отмечена как потерянная

Теперь цена защиты. Очередь с сохранением на диск и подтверждением обработки — 54 000 ₽, карантин с ручной переотправкой — 38 000 ₽, вместе 92 000 ₽. Окупаемость: 92 000 ÷ 14 835 = 6,2, то есть на седьмом месяце. Третья родственная строка — повторные попытки и ключ операции за 46 000 ₽ — в этот расчёт не входит намеренно: она окупается отдельно, через отсутствие дублей, и посчитана в соседней статье кластера.

графикocheredi-i-povtornye-popytki--04
График накопленных потерь 14 835 ₽ в месяц против разового вложения 92 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. 1Остановите получателя на 15 минут и за это время отправьте пять заявок. Включите обратно. Все пять должны появиться у получателя, с исходным временем создания. Ни одна не должна продублироваться.
  2. 2Отправьте заведомо кривую заявку — с артикулом, которого нет в справочнике. Она обязана уйти в карантин с человекочитаемой причиной, а следующие за ней заявки — пройти без задержки. Если встала вся очередь, предела попыток нет.
  3. 3Попросите показать экран очереди и карантина и назовите вслух три числа: сколько сообщений ждёт, какое самое старое, сколько в карантине. Если этих чисел негде посмотреть, значит, эксплуатировать обмен будет невозможно — и поддержка превратится в переписку вслепую.

Когда очередь не нужна

Очередь — не обязательный атрибут любой интеграции. Есть четыре ситуации, в которых мы сами предлагаем обойтись без неё и потратить деньги на что-то другое.

  • Обмен идёт по расписанию, а не по событию. Если система сама приходит и забирает «всё новое с прошлого раза», буфер не нужен: пропущенный запуск догоняется следующим. Это самый дешёвый способ получить свойство «не теряем», и подробно он разобран в статье про обмен по расписанию и по событию.
  • Меньше 150 операций в месяц. Очередь и карантин стоят 92 000 ₽ независимо от объёма. При потоке в 100 заявок потери от недоступности — одна-две заявки в месяц, и разбирать их руками честно дешевле, чем строить контур.
  • Обе системы ваши и стоят в одной сети. Недоступность здесь измеряется минутами в месяц, а перезапуски вы планируете сами и можете просто останавливать обмен на это время. Очередь тут решает проблему, которой почти нет.
  • Данные не критичны и восстанавливаются пересчётом. Обновление остатков, синхронизация цен, выгрузка в аналитику: если следующий запуск всё равно перезапишет состояние целиком, потеря одного сообщения не значит ничего. Буфер нужен там, где сообщение уникально — заявка, заказ, оплата, — а не там, где оно очередной снимок.

И вывод, который стоит держать в голове при разговоре о цене. Очередь не ускоряет обмен, не добавляет функций и ничего не показывает на демонстрации — она покупает единственное свойство: сбой на той стороне перестаёт быть вашей потерей. Стоит это свойство 92 000 ₽ разово и окупается на седьмом месяце, если ваш получатель недоступен хотя бы час в неделю. А недоступен он бывает у всех: обновления, обслуживание базы и перезапуски — это не аварии, это график.

Интеграция без очереди работает ровно до первого планового обслуживания на той стороне.