Задача
Выкатка обновлений большого портала перестала доходить до сервера. Три попытки подряд оборвались, каждая занимала около сорока минут, в логе — «соединение разорвано» и «таймаут». Внешне это одна поломка сети.
Самое дорогое решение здесь — то, которое напрашивается: увеличить таймаут и перезапустить. Оно иногда срабатывает, ничего не объясняет и возвращается через неделю.
Решение
Вместо перезапуска — измерить три вещи по отдельности: сколько данных мы вообще отправляем, что при этом удаляем на сервере и сколько страниц собираем. Один симптом «выкатка оборвалась» распался на четыре независимые причины, и три из них к сети отношения не имели.
Внедрение
1. Отправляли втрое больше нужного
Папка сборки весила 8,1 ГБ, из которых серверу нужны 2,7 ГБ. Остальное — 4,3 ГБ служебных артефактов режима разработки, которые на боевом сервере не используются вообще, и 1,1 ГБ локального кэша сборки. Оба каталога исключены из передачи.
2. Каждый деплой сносил рабочий кэш сайта
Это оказалось хуже медленной выкатки. Синхронизация шла с режимом «удалить на сервере всё лишнее», и под «лишнее» попадал кэш уже готовых страниц, который живёт в том же каталоге. То есть сайт после каждого обновления заново прогревался с нуля — а списывали это на «ну, после деплоя всегда тормозит». Каталог кэша теперь нельзя ни заливать, ни удалять.
3. Таймаут убивал передачу сам
Ограничение в 120 секунд стояло на всю операцию, включая сверку файлов. На 127 000 файлов сверка молчит дольше двух минут — и процесс убивал себя, не передав ни байта. Таймаут поднят до 600 секунд, добавлены докачка оборванных файлов и удержание соединения, чтобы длинная передача не рвалась посередине.
4. Собирали тысячи заведомо пустых страниц
Четыре раздела каталога строились как полное сочетание всех признаков со всеми — регион с типом, станция метро с типом и так далее. Большинство сочетаний пустые: объектов такого типа в этом месте просто нет. Теперь заранее собираются только непустые комбинации: 3 611 → 996, 2 394 → 220, 550 → 135, 189 → 73. Остальные никуда не делись — они открываются по первому запросу и после этого работают как обычные.
Результат
- Объём одной выкатки: 8,1 → 2,7 ГБ, минус две трети.
- Из предварительной сборки ушло около 5 300 страниц — примерно 6 700 сократились до 1 400, при этом ни один адрес не пропал из доступа.
- Кэш готовых страниц переживает деплой, а не собирается заново после каждого обновления.
- Заодно закрыта тихая поломка в том же скрипте: ошибка обновления кода на сервере проходила молча, и выкатка спокойно продолжалась со старой версией. Теперь скрипт на этом останавливается.
Вывод, который переносится на любой проект: «всё тормозит и падает» — это не диагноз, а список симптомов. Час на разбор дал четыре разные причины, две из которых портили сайт незаметно и не имели отношения к тому, на что жаловались.