Агентство загружает фотографии объектов недвижимости. Сервис быстро принимает файлы, ставит задачи на подготовку изображений и сообщает об успехе. Во время массовой загрузки очередь растёт, а новые карточки остаются без фотографий. Технически система доступна. Для сотрудников публикация объектов остановилась.
Буфер помог принять всплеск, но не создал дополнительную производительность. Если работы постоянно приходит больше, чем завершается, увеличение очереди лишь отодвинет момент, когда задержка станет неприемлемой. Нужна обратная связь: обработчик не успевает, значит, источник должен уменьшить подачу.
Что именно называют backpressure
В строгом смысле backpressure — передача ограничения от принимающей стороны к отправляющей. Потребитель сообщает, сколько работы готов принять, либо заставляет источник приостановиться до появления ёмкости. Например, обработчик запрашивает следующую порцию только после освобождения ресурсов. Такой подход лежит в основе Reactive Streams.
Рядом стоят другие механизмы: ограничение скорости, контроль допуска новой работы и отказ от части нагрузки. Они помогают защищать систему, но не всегда образуют обратную связь. Вернуть «занято» клиенту, который немедленно повторит запрос, — ещё не добиться замедления.
Поэтому важно пройти весь путь сигнала. Замедлился исполнитель, перестал брать задания, очередь достигла порога — что изменилось у загрузчика? Если тот продолжает принимать фотографии без ограничений, давление просто переместилось в хранилище. У каждого промежуточного буфера тоже должны быть пределы.
Считать время ожидания, а не только свободное место
Условный расчёт для одинаковых задач: исполнители завершают 100 задач в секунду, а новых приходит 80. Для разбора уже накопленных 6 000 остаётся запас в 20 задач в секунду. При неизменных условиях очередь уйдёт примерно за пять минут, а не за минуту. Если новый поток сравняется со скоростью обработки, накопленное вообще не уменьшится.
Реальная фотография может обрабатываться значительно дольше соседней: другой размер, формат, дополнительные преобразования. Поэтому число сообщений нельзя без проверки превратить в обещанный срок. Нужны скорость завершения, возраст ожидающей работы, количество выполняющихся задач и представление об их стоимости.
И размер очереди, и её возраст полезны, но по отдельности могут обманывать. Несколько постоянно ошибающихся заданий останутся старыми при здоровом основном потоке. Большая свежая очередь может быстро разобрать краткий пик. Следить стоит за распределением ожидания и долей результатов, готовых к нужному сроку.
Не забудьте задачи, уже забранные исполнителями. Они могут исчезнуть из видимой очереди, продолжая занимать память и ожидая внешнюю систему. Если автоматике показывают только оставшийся список, она разрешит новую подачу раньше времени. Лимит незавершённой работы должен учитывать и эту часть.
Принять файл — значит взять на себя обязательство
До подтверждения приёма система ещё может честно отказать в новой загрузке, сохранив черновик у пользователя. После подтверждения нужно понимать, где надёжно лежит исходный файл, как зарегистрирована обработка и каким образом клиент узнает итог. Ограничение очереди не даёт права молча забыть уже принятую работу.
Полезно различать состояния «не принято», «принято и ожидает», «обрабатывается», «готово» и «нужна помощь». Повтор с тем же идентификатором не должен создавать ещё одну копию задачи. Иначе пользователь, пытаясь ускорить публикацию, сам увеличит очередь.
Допустимость отмены зависит от смысла операции. Старое задание на миниатюру можно заменить новым, если исходник сохранён, новая версия полностью делает старую ненужной, а правила продукта это допускают. Удалять таким же способом единственное подтверждение принятого действия нельзя. Политика должна различать заменимую работу и обязательство, которое требуется довести до результата.
Один большой импорт не должен занимать весь день остальных
Общая очередь в порядке поступления проста, пока крупное агентство не загрузит весь архив перед обычной работой остальных клиентов. Можно ограничить незавершённую работу по организации, разделить обработку интерактивных и массовых задач или обеспечить им разные доли ресурсов.
Но постоянный приоритет новых карточек способен навсегда отложить архивный импорт. Нужен минимальный прогресс и для фоновой работы, а не просто красивое название низкого приоритета. Распределение ёмкости должно соответствовать тарифам и реальным обещаниям клиентам.
Не надо путать такие правила с бесконечным добавлением исполнителей. Если они уже перегружают общее хранилище, новые процессы усилят проблему. Ограничения общей скорости и нижележащих зависимостей рассмотрены в описании очередей для сглаживания нагрузки Azure.
Остановиться мало — нужно правильно возобновить поток
Когда очередь опустилась чуть ниже порога, не стоит сразу выпускать все накопленные задания разом. Получится колебание: полный поток, перегрузка, остановка и снова полный поток. Отдельные условия замедления и возвращения, а также постепенное увеличение подачи помогают избежать такого режима.
Ожидание должно иметь предел и у отправителя. Если он не умеет ждать или сохранять работу, обратная связь закончится потерей данных либо отказом. Тогда продукту нужна другая договорённость: ограниченный приём, надёжное отложенное хранение или явно разрешённое отбрасывание. Эти последствия надо назвать заранее, а не обнаруживать при заполнении памяти.
Повторы тоже входят в общий поток. Если каждая отклонённая попытка немедленно создаёт новую, даже обработка отказов становится нагрузкой. Сотрудничество клиента и сервиса при перегрузке описывает Google SRE. Ограниченные повторы с задержкой помогают только при соблюдении общего срока и безопасном повторении операции.
Проверка заканчивается после разбора накопленного
На испытании стоит замедлить обработку фотографий, продолжая обычные загрузки. Проверить пределы памяти и очередей, поведение источника, сохранность принятого и доступность обычной публикации для других клиентов. Затем вернуть производительность и дождаться завершения отложенной работы.
В результате нужны не только графики загрузки серверов, но и судьба каждой принятой тестовой задачи: завершена, явно отменена по правилам или передана на разбор. Измерьте время возвращения к нормальному ожиданию. Система, которая пережила пик, но весь следующий день выполняет вчерашнюю работу, ещё не восстановилась в полезном для бизнеса смысле.