Как ускорить конвейер CI/CD

Современный рынок - это постоянно меняющаяся, постоянно растущая, гипермодернистская среда. Каждый день в мире появляются тысячи новых конкурентов, трансформирующиеся технологии сотрясают отрасли, а новые парадигмы становятся первопроходцами в ведении бизнеса.
В этих условиях быстрые поставки важны как никогда, а заказчики хотят, чтобы их проекты соответствовали требованиям конкурентного рынка, который движется с бешеной скоростью. Непрерывная поставка и разработка (CI/CD) - популярная методология, направленная именно на это, автоматизируя процесс разработки и создавая постоянный цикл.
Но даже в методе, призванном ускорить цикл разработки, могут быть свои "узкие места", и именно об этом мы поговорим сегодня. О том, что мы можем сделать для оптимизации нашего CI/CD-конвейера.

Создавайте только то, что вам нужно

Может показаться заманчивым пытаться продвинуть как можно больше в каждом коммите, но сборка пяти различных модулей или сервисов за один раз часто может привести к большим проблемам, чем это стоит делать.
Правильная политика заключается в том, что каждый коммит должен быть подобен хорошему электронному письму - коротким и по делу. Даже в проектах, основанных на монолитной архитектуре, можно извлечь много пользы, если придерживаться одного модуля за раз.
Сосредоточьте свои усилия на том, что абсолютно необходимо, расставьте приоритеты и сохраняйте простоту. Массивные коммиты часто становятся узкими местами, связанными с обзорами кода, QA и тестированием. Если 99% кода идеально, но одна строка вызывает подозрение, то остальной код может застрять в процессе, пока ошибка будет исправлена.
Если это звучит так, будто кто-то продает архитектуру микросервисов, то это именно так. Хотя монолитные подходы имеют свои сильные стороны, как правило, сохранение всего микро- и разрозненного позволяет сэкономить много времени в долгосрочной перспективе.

Избегайте одновременного внесения слишком большого количества изменений

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

Выполняйте задания параллельно

Конвейеры CI/CD при правильном использовании могут значительно сэкономить время, но, как и труба, они могут выдержать только определенный объем работы. После определенного порога непрерывный цикл разрушается, и образуется узкое место.
Для тех, кто не слишком разбирается в разработке программного обеспечения, скажу, что в большинстве случаев этапы сборки выполняются последовательно. То есть каждый шаг выполняется самостоятельно и только после завершения предыдущего.
Иногда мы можем разбить процесс на отдельные шаги и запускать их одновременно, что принято называть параллельным или одновременным выполнением. Пять заданий, на выполнение каждого из которых требуется минута, при последовательном выполнении займут пять минут, а при параллельном - всего одну минуту.
Очевидно, что не все задания можно выполнять параллельно, да и не нужно. Некоторые задания выполняются достаточно быстро или эффективно, чтобы справиться с нагрузкой. Другие задания могут потребовать больше времени и ресурсов, и в этих случаях процесс можно ускорить, создав другие экземпляры для работы в тандеме.

Кэш, кэш, кэш

Артефакты предыдущих выпусков CI/CD могут быть повторно использованы в новых циклах. Например, пакет или контейнер, необходимый вашему приложению, может быть использован в последующих циклах.
Чтобы избежать необходимости загружать или полностью перестраивать пул ресурсов для каждого цикла, следует кэшировать все и использовать их повторно везде, где это возможно. Для решения подобных задач существуют замечательные инструменты, такие как, например, Artifactory.
Повторное использование ресурсов, которые уже есть под рукой, позволяет значительно увеличить скорость работы CI/CD-конвейера. В то же время снижается риск возникновения проблем, связанных с совместимостью.
Хотя кэши полезны, они не предназначены для вечного использования. Важно удалять кэш при обновлении или когда в нем больше нет необходимости, это позволит избежать путаницы в дальнейшем.

Использование "канареечных" релизов

Некоторые команды DevOps выпускают предварительные сборки для небольшого подмножества пользователей и собирают отзывы, прежде чем приступить к полной фиксации сборки. Canary-релизы помогают собрать полезные данные об изменениях, не подвергая всю пользовательскую базу потенциальным ошибкам и проблемам.
Большие команды разработчиков могут даже создавать различные канареечные выпуски, каждый из которых предназначен для разных подмножеств пользователей. Таким образом, различные изменения можно оценивать параллельно и легче выявлять потенциальные проблемы.
Например, если у вас есть три группы пользователей - A, B и C, и группа A сообщает об ошибке, то вы знаете, что что-то происходит именно с этим канареечным выпуском. Таким образом, легче отследить источник проблемы.

Анализ конвейера

Мы оставили самое важное напоследок. Мы не можем не подчеркнуть, насколько важно для команды постоянно контролировать CI/CD-конвейер. Измерьте, сколько времени занимает каждый цикл, и внимательно посмотрите на те работы, которые занимают больше всего времени.
Используется ли это время на высокоценных этапах? Если это не так, то что можно сделать, чтобы сократить общее время или перетасовать шаги?
Есть ли длинные этапы, которые не приносят пользы? Зачем они нужны? Можно ли их безопасно убрать?
Поняв свой собственный конвейер, вы сможете принимать более правильные решения о том, как увеличить скорость каждого цикла. Помните, что разработка CI/CD-конвейера - это итеративный процесс. Вы должны продолжать работать над ним и постоянно контролировать его, чтобы найти области для улучшения.