# Ночная сборка шла четыре с половиной часа

## Вопрос заказчика

«Можно ли распараллелить сборку и сколько для этого нужно ресурсов?» — обычная заявка от команды разработки. Сборка конфигурации с автотестами шла около четырёх с половиной часов, то есть за ночь успевал ровно один прогон. Ошибку, найденную утром, можно было проверить только следующей ночью.

Правильный ответ на такой вопрос начинается не с настройки, а с замера.

## Что показал замер

Разобрали конкретный прогон по журналу, с точностью до отдельных шагов:

| Блок | Время | Чем определяется |
| --- | --- | --- |
| Подготовка баз | ~86 мин | обновление конфигурации демонстрационной базы из хранилища — ~75 мин, операция однопоточная |
| Проверка качества | ~180 мин | четыре прогона тестов подряд: ~8, ~74, ~37 и ~58 минут |
| Прочее | ~4 мин | — |

Первое открытие: параллельность в сборке **уже была**. Ветки проверки синтаксиса, дымовых и модульных тестов шли одновременно и завершались рано, после чего просто ждали. Весь блок упирался в одну ветку — функциональные тесты, где четыре прогона выполнялись строго друг за другом.

Второе открытие: причина последовательности — не в настройке сборки, а в том, что все четыре прогона работали с **одной и той же тестовой базой** и мешали друг другу блокировками. Тот же класс проблемы ранее приводил к зависанию сборки целиком.

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

## Что предложили

**Разделить тестовые базы.** Каждому параллельному потоку — своя копия базы. Тогда блок проверки качества ужимается со ста восьмидесяти минут до длины самого долгого прогона — примерно семидесяти пяти. Общая длительность сборки падает с четырёх с половиной часов до трёх, то есть примерно в полтора раза.

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

**Посчитали, чего это стоит в ресурсах.** Ограничитель — не агент сборки, а серверы за ним: каждому потоку нужна своя копия базы, своя сессия на сервере приложений и запас в СУБД. Указали конкретно: серверу базы данных нужно втрое больше памяти и в полтора раза больше процессоров, серверу приложений — прибавка памяти из расчёта на каждую дополнительную сессию, плюс место под копии баз. Отдельно отметили соседний сервер базы, у которого диск занят на восемьдесят пять процентов, — до него скоро тоже дойдёт очередь.

![Измеренная сборка около 270 минут и невнедрённый прогноз сокращения до 3 часов](/images/illustrations/part2/18-case-ci.webp)

## Результат

**Работа закончилась расчётом, а не внедрением.** Полтора раза — это прогноз по замерам, а не достигнутое ускорение: разделение баз и закупка ресурсов в объём этой задачи не входили.

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

Решение о том, стоит ли выигрыш в полтора часа требуемых ресурсов, принимает бизнес. Наше дело — дать ему цифры, а не ощущения.