
Пока пользователи спят, цифровые сервисы продолжают выполнять невидимую работу: создают резервные копии, обрабатывают очереди, пересчитывают данные и синхронизируют хранилища. IT-инженер Никита Кузнецов объясняет, почему ночные процессы могут стать причиной утренних задержек, как незаметная деградация превращает миллисекунды в секунды ожидания и зачем инженерам следить не только за «зелёными» индикаторами.
В три часа ночи цифровой мир со стороны пользователя действительно выглядит почти пустым. Смартфоны стоят на зарядке, ноутбуки закрыты, рабочие чаты затихают, а число обращений к большинству сервисов снижается до минимума. Однако внутри инфраструктуры в это время может начинаться одна из самых напряжённых частей суток. Серверы создают резервные копии, базы данных обслуживают индексы, системы архивируют старые записи, очищают временные данные, пересчитывают статистику, синхронизируют хранилища и разбирают накопившиеся очереди.
Ночь для подобных операций выбирают не случайно: активных пользователей меньше, а значит, тяжёлые процессы можно провести с меньшим риском повлиять на работу приложения или сайта. Но сокращение числа посетителей вовсе не означает, что снижается вычислительная нагрузка. Иногда именно в три часа ночи инфраструктура работает интенсивнее, чем это можно предположить по графику посещаемости.
IT-инженер Никита Кузнецов предлагает рассматривать такую ночную работу не как второстепенное техническое обслуживание, а как продолжение жизни самого продукта. Пользователь видит сайт, приложение или кнопку оплаты. За этим интерфейсом существует система, которая продолжает меняться и после релиза: растут базы данных, появляются новые зависимости, увеличиваются очереди, усложняются фоновые операции. Сервис может не переживать заметных аварий, но при этом месяцами становиться тяжелее и медленнее.
«Меня всегда настораживает фраза: “Ночью пользователей почти нет, значит, система отдыхает”. Она не отдыхает. В это время может идти самая тяжёлая внутренняя работа за сутки. Backup читает огромные объёмы данных, фоновые задачи разбирают очереди, пересчитывается статистика, обслуживаются хранилища. Пользователь этого не видит — и в нормально построенной системе не должен видеть. Но инженер обязан понимать, что происходит внутри и сколько ресурсов эта ночная работа забирает», — объясняет Никита Кузнецов.
В три часа ночи у сервиса начинается вторая смена
Часть работы современного приложения не имеет смысла выполнять прямо в момент, когда пользователь ждёт ответа. Например, покупатель интернет-магазина нажимает кнопку оплаты и получает подтверждение заказа. Для него операция завершена. Но внутри системы после этого могут обновляться остатки товаров, передаваться информация на склад, записываться события для аналитики, отправляться уведомления, синхронизироваться данные с бухгалтерией и формироваться документы.
Если заставить пользователя ждать завершения всей этой цепочки, интерфейс начнёт ощутимо тормозить. Поэтому основная операция выполняется сразу, а часть внутренних действий отправляется в фон. За сутки таких задач могут накопиться миллионы. К ним добавляются резервное копирование, очистка журналов событий, архивация, обновление поисковых индексов, пересчёт агрегированных показателей, формирование отчётов и синхронизация данных между хранилищами.
Ночное окно выглядит удобным временем для таких процессов. Проблема начинается в тот момент, когда сразу несколько тяжёлых операций претендуют на одинаковые ресурсы. В два часа ночи может стартовать резервное копирование крупной базы, через полчаса — суточный аналитический расчёт, а в три часа — архивация старых записей. Параллельно продолжают работать обработчики очередей.
Каждая из этих задач по отдельности может быть штатной и полностью исправной. Однако резервное копирование активно читает данные с диска, аналитика создаёт тяжёлую нагрузку на базу, архивация одновременно читает и изменяет записи, а очередям также требуются соединения с той же базой данных. Сервер при этом не обязательно выйдет из строя. Внешне всё может оставаться работоспособным, но операции, которые прежде занимали десятки миллисекунд, начинают выполняться медленнее.
«Я вообще не люблю делить систему только на два состояния — “работает” и “не работает”. Между ними огромная территория. Сервис может отвечать, не выдавать ошибок и при этом уже несколько месяцев медленно деградировать. Запрос занимал 120 миллисекунд, потом 170, потом 250. Ночная задача выполнялась двадцать минут, потом сорок, потом два часа. Формально всё зелёное. Но инженер уже должен видеть проблему. Ждать момента, когда пользователь скажет “у вас всё тормозит”, — значит прийти слишком поздно», — говорит Никита Кузнецов.
Мощный сервер не означает быстрый сервис

Никита Кузнецов — о том, почему постепенная деградация системы может долго оставаться незаметной пользователю
Распространённая ошибка — объяснять медленную работу приложения недостаточной мощностью оборудования. Если сервис тормозит, первым решением нередко становится покупка более производительных серверов, увеличение объёма оперативной памяти или перенос системы на дорогую конфигурацию. В отдельных случаях это действительно даёт эффект, однако производительность сложной цифровой системы не сводится к числу процессоров и объёму памяти.
Приложение может почти не нагружать процессор, но ждать завершения операций с диском. Диск, в свою очередь, может быть занят большим числом операций ввода и вывода. База данных может ожидать освобождения блокировки, приложение — свободного соединения с базой, один внутренний сервис — ответа другого, а тот — данных от внешнего API. В результате загрузка CPU остаётся умеренной, память доступна, сервер формально здоров, но пользователь продолжает ждать.
Никита Кузнецов сравнивает такую ситуацию с дорогой, на которой возникло узкое место. Можно увеличить мощность автомобилей или добавить новые машины, однако пропускная способность не изменится, если впереди остаётся одна полоса. В цифровой инфраструктуре такой «одной полосой» могут оказаться база данных, сеть, диск, пул соединений, очередь, конкретный внутренний сервис или внешняя зависимость.
«Сильный инженер для меня — не человек, который быстрее всех перепишет функцию. Иногда функцию вообще не надо трогать. Нужно увидеть, что она 80 миллисекунд ждёт соседний сервис, тот ещё 300 миллисекунд ждёт базу, а база в это время конкурирует с ночной аналитикой. Если смотреть только на собственный кусок кода, можно неделю оптимизировать то, что занимает пять процентов общего времени», — объясняет Никита Кузнецов.
Добавление ресурсов в такой ситуации может временно улучшить показатели. Более мощная база данных выдержит больше запросов, быстрый диск сократит задержки, а дополнительные серверы помогут распределить нагрузку. Но если архитектурная причина не устранена, рост аудитории и объёма данных постепенно съест полученный запас. По мнению Никиты Кузнецова, масштабирование оборудованием имеет смысл только тогда, когда команда понимает, какое именно ограничение снимает. Иначе компания покупает не решение, а отсрочку до следующего повторения проблемы.
Как миллисекунды превращаются в секунды

Никита Кузнецов: ночные фоновые процессы становятся частью реальной нагрузки на инфраструктуру
Пользователь нажимает одну кнопку, но цифровой сервис редко выполняет лишь одно действие. Запрос способен пройти через балансировщик нагрузки, систему авторизации, само приложение, кэш, базу данных и несколько внутренних сервисов. Один из компонентов может обратиться к следующему, тот — запросить данные в собственном хранилище, а часть информации дополнительно получить через внешний API. Лишь после этого формируется окончательный ответ.
У каждого участка есть собственная задержка. Например, обращение к базе данных раньше занимало 25 миллисекунд, а после роста таблицы стало занимать 60. Внутренний сервис отвечал за 20 миллисекунд, затем — за 45. Проверка прав добавила ещё 30, новый компонент — 50, внешний API стал отвечать медленнее ещё на 100 миллисекунд. Каждая отдельная цифра может казаться незначительной, но пользователь ждёт не отдельный компонент, а завершение всей цепочки.
Особенно заметной проблема становится там, где операции нельзя провести одновременно. Второй сервис не может начать работу, пока не ответил первый, третий ожидает результат второго, а обращение к базе возможно только после получения этих данных. В таком случае задержки складываются почти напрямую. Десятки миллисекунд постепенно становятся сотнями, а затем и секундами.
«Когда мне говорят, что сервис стал медленным, первое, что хочется сделать, — убрать само слово “медленный”. Оно ничего не объясняет. Покажите конкретный запрос. Сколько он шёл? Где провёл это время? Сколько заняла база? Сколько сеть? Сколько внешний API? Были ли повторные запросы? Попали мы в кэш или пошли за исходными данными? После этого появляется инженерный разговор. До этого у нас просто ощущение пользователя, которое ещё нужно разложить на измеряемые части», — говорит Никита Кузнецов.
Когда защита от сбоя сама создаёт нагрузку

Никита Кузнецов — о мониторинге, задержках и поиске узких мест в цифровых сервисах
Дополнительную сложность могут создавать механизмы, которые изначально предназначались для повышения устойчивости системы. Один из понятных примеров — повторные запросы. Если внешний сервис или внутренняя зависимость не ответили вовремя, приложение может попытаться обратиться к ним ещё раз. На первый взгляд логика кажется разумной: первая попытка не сработала — нужно сделать вторую.
Однако первый запрос не обязательно прекратил выполняться. Сервер мог не успеть ответить до истечения установленного времени ожидания, но продолжать обработку. В этот момент к нему приходит новый запрос. Если и он кажется слишком медленным, появляется третий. Когда так действуют не один пользователь, а тысячи клиентов или внутренних процессов одновременно, механизм устойчивости начинает создавать дополнительную нагрузку.
«Повтор запроса кажется естественной защитой: не получилось — попробуй ещё раз. Но в распределённой системе нужно задать следующий вопрос: что произойдёт, если одновременно “попробуют ещё раз” десять тысяч клиентов? Механизм устойчивости не должен превращаться в генератор дополнительной нагрузки. Timeout, retry, количество попыток и интервалы между ними нельзя проектировать независимо друг от друга», — считает Никита Кузнецов.
Среднее время ответа способно обмануть
Среднее время ответа — понятная и удобная метрика, но она может скрывать неприятную картину. Допустим, большинство запросов обрабатывается за 150–200 миллисекунд, однако небольшая часть операций занимает несколько секунд. Быстрые ответы снижают среднее значение, и график может выглядеть благополучно. Пользователь не видит общую статистику: если именно его платёж, сохранение документа или открытие страницы заняло пять секунд, сервис для него был медленным.
Поэтому при эксплуатации крупных систем инженеры анализируют не только средние значения, но и перцентили задержек — p50, p95 и p99. P50 показывает типичное время выполнения операции. P95 позволяет увидеть значение, в которое укладываются 95% запросов. P99 помогает обнаружить более редкий, но важный медленный «хвост». Даже один процент от десяти миллионов операций означает сто тысяч запросов.
«Среднее значение очень удобно для самоуспокоения. Допустим, девяносто девять человек получили ответ быстро, а сотый ждал пять секунд. В среднем сервис может выглядеть прекрасно. Только этому сотому человеку совершенно всё равно, насколько быстро обслужили остальных. Поэтому меня интересует не только среднее. Я хочу видеть хвост — p95, p99, самые медленные сценарии и причину, по которой именно они отличаются от остальных», — объясняет Никита Кузнецов.
«Мы ничего не меняли» — одна из самых опасных фраз
Система может начать работать медленнее и без нового релиза. Одной из причин становятся данные. Представим запрос к таблице со ста тысячами записей. Даже не самый удачный запрос на таком объёме способен выполняться быстро. Через несколько лет таблица может вырасти до ста миллионов строк. Код останется прежним, но объём работы изменится радикально.
Сначала время выполнения увеличится с 20 до 35 миллисекунд, затем до 70, потом до 150. Не будет конкретного дня, когда запрос «сломался». Сервис просто постепенно перерастёт те предположения о данных и нагрузке, на которых строилось первоначальное архитектурное решение.
«Одна из моих любимых фраз на разборе проблем — “мы там ничего не меняли”. Хорошо. А данные? Их тоже не стало больше? Пользователей не прибавилось? Таблица не выросла со ста тысяч строк до ста миллионов? Соседних сервисов не появилось? Код может оставаться тем же самым, а среда вокруг него полностью измениться. Поэтому отсутствие релиза не означает отсутствия изменений в системе», — говорит Никита Кузнецов.
Ночная задача может быть успешной и одновременно становиться проблемой

Никита Кузнецов: миллисекунды на отдельных этапах запроса в итоге могут складываться в заметную пользователю задержку
Представим процесс, который каждый день стартует в два часа ночи. Год назад он завершался в 02:20, затем — в 02:40, спустя несколько месяцев — в 03:30. Сегодня операция заканчивается почти в шесть утра. В журнале при этом ежедневно появляется отметка success. Если команда контролирует только факт успешного завершения, она может не заметить проблемы. Стоит посмотреть на продолжительность выполнения — и картина меняется.
Постепенное удлинение ночных задач особенно опасно потому, что в определённый момент они начинают пересекаться с утренним пользовательским трафиком. Процесс, который прежде завершался задолго до начала рабочего дня, остаётся активным в часы роста нагрузки. Тогда проблема, которую долго можно было наблюдать только во внутренних графиках, становится заметна пользователям.
«Представьте процесс, который каждый день стартует в два часа ночи. Год назад он заканчивался в 02:20. Сегодня — в 05:40. Но на дашборде каждый день написано success. Можно год смотреть на зелёную галочку и считать, что всё прекрасно. Я бы смотрел не на галочку, а на эти три лишних часа. Потому что однажды задача закончит работу не в пять сорок, а в девять утра и встретится с основным пользовательским трафиком. Вот тогда техническая проблема станет видна уже не инженеру, а клиенту», — объясняет Никита Кузнецов.
Очередь может расти, пока все серверы показывают зелёный статус
Очереди нужны для того, чтобы не выполнять всю работу синхронно. Допустим, система каждую минуту получает 10 тысяч задач, а обработчики успевают выполнить 9,5 тысячи. Через минуту остаётся 500 необработанных сообщений, через час — уже 30 тысяч. При этом серверы доступны, обработчики работают, а ошибок может почти не быть. Система просто принимает работу быстрее, чем может выполнить.
Проблема в таких случаях не всегда заметна по одному моментальному показателю. Важнее смотреть на динамику. Если в очередь каждую секунду приходит десять тысяч задач, а обрабатывается двенадцать тысяч, система постепенно разгребает накопившуюся работу. Если же приходит десять тысяч, а выполняется девять, очередь будет расти, даже если сейчас она кажется небольшой.
«Я бы вообще не пугался большой очереди только потому, что она большая. Нужно спросить: она движется? Если туда каждую секунду приходит десять тысяч задач, а уходит двенадцать тысяч — система разгребает работу. Если приходит десять тысяч, а обрабатывается девять — у нас уже есть проблема, даже если очередь пока выглядит маленькой. Через час она будет другой. Через ночь — совсем другой. Инженеру важно смотреть не только на фотографию состояния, но и на направление движения», — говорит Никита Кузнецов.
Кэш способен скрывать проблему годами
Кэширование позволяет не выполнять дорогую операцию при каждом запросе. Если одни и те же данные нужны многим пользователям, результат можно сохранить в быстром промежуточном хранилище и выдавать оттуда. База данных получает меньше обращений, а время ответа снижается. Однако записи в кэше имеют ограниченный срок жизни.
Если большое число популярных данных исчезает из кэша одновременно, следующие запросы обращаются уже к первичному источнику. Тысячи операций, которые прежде обрабатывались быстрым кэшем, внезапно приходят в базу данных. И тогда может выясниться, что исходный путь получения данных давно стал слишком дорогим для реальной нагрузки.
«Кэш иногда создаёт опасную иллюзию. Вы годами видите быстрый сервис и начинаете думать, что исходная операция тоже быстрая. Потом кэш массово промахивается — и внезапно выясняется, что получение данных без него давно стало очень дорогим. Поэтому я хочу знать не только, насколько хорошо работает кэш, но и что произойдёт с системой, если завтра его эффективность резко упадёт», — отмечает Никита Кузнецов.
Инженеру нужно знать, где лежат конкретные 1,8 секунды
Когда запрос выполняется 1,8 секунды, одной итоговой цифры недостаточно. Для понимания причин применяются метрики, логи и распределённая трассировка. Метрики позволяют увидеть тенденции, логи фиксируют события, а distributed tracing помогает пройти путь конкретного запроса через несколько компонентов и определить, сколько времени он провёл на каждом этапе.
Например, весь запрос занял 1,4 секунды. Само приложение выполняло вычисления 70 миллисекунд, база данных — 90, кэш и внутренние операции — ещё 60. Более секунды ушло на ожидание внешнего API. Если этого не видно, команда может несколько дней оптимизировать собственный код и выиграть 15 миллисекунд в ситуации, где основная проблема измеряется целой секундой.
«Для меня хороший мониторинг — это не телевизор на стене с двадцатью зелёными графиками. У меня есть запрос, который шёл 1,8 секунды. Я хочу открыть его и понять, куда ушли эти 1,8 секунды. Если 1,2 секунды мы ждали внешнего провайдера, бессмысленно оптимизировать код приложения ради десяти миллисекунд. Если мы этого не видим, мы не диагностируем систему. Мы угадываем», — говорит Никита Кузнецов.
Самая важная миллисекунда — та, которую пользователь ещё не заметил

Никита Кузнецов: скорость сервиса складывается из работы множества внутренних компонентов
Производительность цифрового продукта особенно легко теряется постепенно. В январе p95 мог составлять 180 миллисекунд, весной — 230, летом — 300. Ночная обработка, занимавшая 40 минут, начинает работать полтора часа. Запрос к базе данных становится вдвое тяжелее, новый внутренний сервис добавляет сетевой переход, а внешний провайдер отвечает немного медленнее.
Ни одно такое изменение само по себе не обязательно выглядит катастрофой. Однако в совокупности они меняют пользовательское восприятие продукта. Сервис, который раньше открывался почти незаметно, начинает требовать ожидания. Пользователь не знает, что именно стало причиной: рост базы данных, очереди, повторные запросы, кэш или внешний API. Он формулирует проблему просто: «Всё стало тормозить».
«Скорость продукта нельзя получить один раз. Нет точки, в которой команда сказала: “Теперь наш сервис быстрый”, — и закрыла этот вопрос навсегда. Завтра станет больше данных, послезавтра появится новая интеграция, через месяц изменится характер нагрузки. Где-то добавятся двадцать миллисекунд, где-то пятьдесят, где-то ночная задача станет работать на час дольше. Моя задача как инженера — увидеть эти изменения до того, как пользователь соберёт их в одну фразу: “У вас всё стало тормозить”», — объясняет Никита Кузнецов.
Пользователь утром должен увидеть только работающую кнопку
В три часа ночи сервис способен перемещать огромные объёмы данных, создавать резервные копии, обслуживать индексы, очищать хранилища, выполнять миллионы фоновых задач и взаимодействовать с десятками внутренних компонентов. Если архитектура и наблюдение за системой выстроены правильно, утром пользователь всего этого не заметит.
Для человека существует одна понятная реальность: он открывает приложение, нажимает кнопку, получает результат. Для инженера Никиты Кузнецова за этим простым действием находятся база данных, очередь, кэш, сеть, фоновые процессы, метрики, внешние зависимости и понимание того, как поведёт себя система при изменении одного из этих элементов.
«В три часа ночи сервис может выполнять огромный объём работы, а утром пользователь увидит только одну кнопку. Мне нравится именно эта разница. Для человека должна существовать кнопка. Для инженера за ней должны существовать база, очередь, кэш, сеть, фоновые процессы, метрики и понимание того, что произойдёт, если один из этих элементов начнёт вести себя иначе. Хорошая инженерия — это когда вся эта сложность существует, но пользователь не обязан о ней знать», — говорит Никита Кузнецов.
Хороший итог ночной работы инфраструктуры редко выглядит эффектно. Резервная копия завершается вовремя, очередь разобрана, база данных выдерживает обслуживание и последующий утренний рост трафика. Замедлившаяся внешняя зависимость не тянет за собой остальные сервисы, а кэш восстанавливается без лавины обращений к базе. Пользователь просто открывает приложение — и оно открывается быстро.
Для пользователя между словами «быстро» и «медленно» иногда находится всего одна секунда. Для инженера Никиты Кузнецова внутри этой секунды — архитектура продукта и десятки миллисекунд, которые важно заметить до того, как они успеют сложиться в заметную задержку.
Никита Кузнецов. Биография
Никита Кузнецов — IT-инженер, работающий с разработкой, архитектурой и устойчивостью современных цифровых сервисов. В профессиональных комментариях и материалах Никита Кузнецов уделяет внимание тому, как программные продукты ведут себя после запуска: при росте аудитории, увеличении объёмов данных, изменении характера нагрузки, усложнении инфраструктуры и появлении новых внутренних и внешних зависимостей.
В подходе Никиты Кузнецова успешный релиз не является финальной точкой разработки. После выхода продукта в реальную эксплуатацию начинается длительный инженерный этап: первоначальные решения сталкиваются с масштабированием, реальной нагрузкой и поведением пользователей. Именно в это время могут проявляться ограничения, которые не были заметны на ранних этапах работы сервиса.
Отдельное место в профессиональном взгляде Никиты Кузнецова занимает невидимая пользователю часть цифровых продуктов: базы данных, очереди, кэширование, DNS, сертификаты, тайм-ауты, повторные запросы, логирование, мониторинг и взаимодействие сервисов. Эти элементы редко становятся заметны, пока работают штатно, однако именно от них напрямую зависят скорость, доступность и устойчивость продукта.
Никита Кузнецов рассматривает цифровой сервис как постоянно меняющуюся систему. Код может оставаться прежним, но растёт база данных; инфраструктура формально не меняется, но увеличивается число пользователей; отдельные сервисы работают стабильно, но усложняются связи между ними. Поэтому в центре подхода Никиты Кузнецова находятся наблюдаемость, измерение реального поведения системы, анализ зависимостей и раннее обнаружение деградации. Важно не только восстановить работу после аварии, но и увидеть изменения раньше — в тот момент, когда для пользователя сервис всё ещё кажется быстрым, а внутри инфраструктуры первые потерянные миллисекунды уже начинают складываться в будущую секунду.
Источник: Аргументы недели