Как ускорить Jenkins?

время 5 МИН
звезда звезда звезда СРЕДНЕ
Jenkins
CI/CD
Автоматизация

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

Когда пишешь новый функционал, перед тем как передать код на ревью, хорошо убедиться что сборка в Jenkins прошла успешно и тогда с чистой совестью можно взяться за новую задачу. Можно конечно взяться и не дожидаясь, но потом возвращаться будет больнее, переключение контекста вещь не приятная.

Как же получить результат быстрее?

Запустить сборку как можно раньше

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

Можно так же запускать сборки периодически по таймеру. Встает вопрос как часто? Если слишком часто возможно никаких изменений кода за небольшой промежуток не было, зря потратим ресурс Jenkins (собирать одно и тоже не имеет смысла, результат будет тот же). Если запускать слишком редко ожидание старта сборки может быть дольше самой сборки (если запускать раз в час или раз в сутки например).

Но есть способ лучше, можно настроить запуск сборки по событию, скажем на пуш кода в репозитории, тогда процесс запустится моментально после изменений кода. Если вы часто делаете пуши, чаще чем проходят сборки, тогда имеет смысл разрешить конкурентные сборки, иначе комиты будут стоять в очереди на сборку и результат самого последнего (и самого важного) коммита придется снова ждать. Тут либо увеличивать мощность инфраструктуры Jenkins чтобы позволял обрабатывать больше сборок в единицу времени, либо если сборка еще не закончена, а пришел новый коммит, можно текущую сборку отменить автоматически, все равно же важно получить результат только для последнего коммита. Но все же полезно иметь результаты и для промежуточных, видно когда код сломался, быстрее починить пока контекст в голове свежий.

Ускорить сборку

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

Почему еще сборки могут идти долго?

Сборки стали в очередь из-за нехватки мощностей Jenkins (банально ждут свободного агента когда все заняты). В таком случае лучше всего проапгрейдить инфраструктуру.

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

Минимизировать перезапуски

Бывает сборка, падает случайным образом, а не от того что сломали код в данном коммите. Причины:

Нестабильные тесты. Если тест написан на метод который возвращает не упорядоченное множество, а тест ожидает конкретный порядок, такой тест иногда может проходить успешно, а иногда нет. Или остался мусор от предыдущих сборок в виде файлов или данных в БД например при первом запуска тестовые пользователи создались нормально, а при повторном уже ошибка - дубликаты в базе.

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

Неконтролируемое обновление инфраструктуры. Бывает так что код перестает собираться после обновления средства сборки (JDK, Node, NPM, Gradle или еще чего), так может случиться если сборки запускать на агентах напрямую, а не внутри контейнеров и если команда DevOps внезапно обновили на агентах инфраструктуру и ваши сборки перестали проходить даже на том же коде, что раньше проходили

Проблемы с инфраструктурой. Так же частая причина случайных падений. Вдруг из-за перебоев сети отвалился Jenkins-agent или приложение не смогло скачать зависимости из репозитория.

Выводы

1. Запускаем билды по событию
2. Параллелим стадии сборки
3. Прекращаем зависшие билды по таймауту
4. Автоматически отменяем билды если пришел новый код
5. Бережные сборки
6. Увеличить мощность инфрастуктуры при необходимости
7. Контролируем версии компонентов и утилит сборки чтобы в продакшене был только протестированный код
8. Стабилизируем тесты

Спасибо, что заглянули,
добавляйтесь в Telegram канал и будьте в курсе новинок.
Если Вам было интересно, можете поддержать автора

Что еще почитать?

Что такое Jenkins?

2023, 19 АВГУСТА
время 3 МИН
звезда звезда звезда ЛЕГКО
Основы
Jenkins
CI/CD
Автоматизация
Поговорим про то, что такое Jenkins, зачем он нужен и можно ли обойтись без него

Как пишут программы?

2023, 19 АВГУСТА
время 4 МИН
звезда звезда звезда ЛЕГКО
Основы
Расскажу о проессе разработке программного обеспечения
на главную