[Перевод] #NoDeployFriday: помогает или вредит?

z2crgd36lx-db7jzcl4oroksz_s.jpeg


Нужно ли запрещать деплоить в production в определённое время? Или движение #NoDeployFriday стало реликтом времён, когда не было всеобъемлющих интеграционных тестов и непрерывного деплоймента?

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


Уверен, что инженеры, имевшие счастье быть «на связи», лишались выходных из-за всё сломавших пятничных изменений. Я тоже был в такой ситуации. Телефонный звонок во время выхода с семьёй или посреди ночи, уведомляющий о падении приложения. После того, как залезешь в компьютер и проверишь быстро растущие логи, становится очевидно, что всё порушило редкое необработанное исключение. Отвратительно.

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

В понедельник проводится встреча «пять почему».

»Давайте просто прекратим деплоить по пятницам. Тогда на выходных всё будет стабильно работать, а на следующей неделе мы будем начеку после всевозможных релизов».

Все кивают. Если что-то не уходит в эксплуатацию до полудня четверга, то оно ждёт до утра понедельника. Такой подход вредит или помогает?

Do you not trust your code and your unit / integration tests that much that you make Friday «code freeze day»? What are we in 2006?

— Josh Dvir (@joshdvir) April 12, 2019


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

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

It’s the worry that is concerning. My favourite projects were those where we pushed any time, any place, because we knew things were going to work. That feeling is far greater than the 2-day weekend relaxation.

— AJ (@antony) April 17, 2019


Другие пользователи полагают, что возможным решением проблемы может быть внедрение флагов функций.

You’re doing it wrong, use a feature toggle push it to prod and do a gradual rollout. Deploy on Saturday too.

— Jeff Gibson (@GibbyMT) April 13, 2019


Этот пользователь считает, что проблемы рискованного деплоя не должно возникать благодаря доступным нам сегодня процессами и инструментам.

You know it’s 2019, right?

— jorn jorn of the rundeckians! (@jorn_knuttila) April 15, 2019


Кто принимает решения?


Весь этот обмен мнениями свидетельствует о том, что мы, как сообщество инженеров, можем сильно расходиться во мнениях и не обязательно соглашаться друг с другом. Кто бы мог подумать. Вероятно, эта ситуация также демонстрирует, что общая картина с #NoDeployFriday содержит такие нюансы, которые не слишком хорошо отражены в Твиттере. Верно ли, что мы все должны применять непрерывный деплоймент, а иначе «делаем неправильно»?

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

Заняв позицию идеалиста, можно предположить, что в идеальном мире с идеальным кодом, идеальным покрытием тестами и идеальным QA никакие изменения не смогут привести к проблеме. Но мы люди, а людям свойственно ошибаться. Всегда будут какие-то странные пограничные случаи, которые не закрыты при разработке. Это жизнь. Так что движение #NoDeployFriday имеет смысл, хотя бы теоретически. Однако это лишь слепой инструмент. Я считаю, что оценивать сделанные изменения нужно в зависимости от ситуации, и априори нужно исходить из того, что мы деплоим в любой день, даже по пятницам, но при этом должны иметь возможность изолировать те изменения, которые должны подождать до понедельника.

Есть некоторые вопросы, которые мы можем обсудить. Я поделил их на категории:

  1. Понимание «радиуса поражения» изменения.
  2. Продуманность процесса деплоя.
  3. Способность автоматически определять ошибки.
  4. Сколько времени уходит на решение проблем.


Теперь давайте обсудим.

Понимание «радиуса поражения»


Когда в онлайне опять начинают ломать копья про пятничные релизы, всегда забывают о важном — о самой природе изменений. Не бывает одинаковых изменений в кодовой базе. Одни коммиты немного правят интерфейс и ничего более; другие рефакторят сотни классов, не затрагивая функциональность программы; третьи меняют схемы базы данных и вносят серьёзные изменения в процесс потребления данных в реальном времени; четвёртые могут перезапустить один экземпляр, в то время как пятые способны инициировать каскадный перезапуск всевозможных сервисов.

Глядя на код, инженеры должны хорошо представлять «радиус поражения» вносимых изменений. Какая часть кода и приложения будет подвержена влиянию? Что может упасть, если новый код будет сбоить? Это всего лишь клик по кнопке, который выкинет ошибку, или будут потеряны все новые записи? Изменение вносится в один изолированный сервис, или синхронно поменяются многие сервисы и зависимости?

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

Здесь нужно принимать решения в зависимости от ситуации. Каждый ли инженер осознаёт «радиус поражения» изменений в production-среде, а не только в среде разработки? Если нет, то почему? Можно ли улучшить документацию, обучение и отображение влияния изменений кода в production?

«Радиус поражения» маленький? Запускайте в пятницу.

«Радиус поражения» большой? Ждите до понедельника.

Продуманность процесса деплоя


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

Процесс полной автоматизации развёртывания — вещь интересная. Он позволяет вам отступить назад и попробовать абстрагировать то, что должно произойти с момента инициализации pull request до отправки приложения в эксплуатацию. Описание всех шагов в коде, например, в упомянутых выше инструментах, поможет вам обобщить определения шагов и повторно использовать их во всех приложениях. К тому же вам будет интересно отметить некоторые странные или ленивые решения, которые вы когда-то приняли и с которыми смирились.

Каждому инженеру, который прочитал предыдущие два параграфа и отреагировал в стиле «Ну конечно! Мы это делаем годами!» я могу гарантировать, что ещё 9 других представили свою инфраструктуру приложения и скривились, осознав объём работы, который нужно проделать для перевода системы на современный конвейер деплоя. Это подразумевает использование преимуществ современных инструментов, которые не только выполняют непрерывную интеграцию, но и позволяют непрерывно поставлять баги в прод, причём инженерам достаточно нажать кнопку для ввода в эксплуатацию (или вообще делать это автоматически, если вы достаточно смелы).

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

С момента мерджа pull request«а до внесения коммита должен быть автоматизирован настолько, чтобы вам даже не нужно было думать об этом. Это не только помогает изолировать реальные проблемы в QA, потому что единственной переменной является изменённый код, но делает написание кода куда более приятным делом. Введение в эксплуатацию децентрализуется, что повышает личную автономность и ответственность. А это, в свою очередь, приводит к более обдуманным решениям относительно того, когда и как выкатывать новый код.

Надёжный конвейер деплоя? Выкатывайте в пятницу.

Вручную копируете скрипты? Ждите до понедельника.

Способность определять ошибки


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

Эксплуатация всегда отличается от разработки, и инженерам нужно отслеживать работу определённых частей системы. Нужно отвечать на вопросы о каждом последующем изменении: оно ускорило или замедлило систему? Таймаутов стало больше или меньше? Мы ограничены по процессору или по вводу/выводу?

Данные по метрикам и ошибкам должны передаваться в систему предупреждения. У команд должна быть возможность определять, какие сигналы свидетельствуют о негативной ситуации, и рассылать автоматические сообщения об этом. Для наших команд и самых серьёзных инцидентов мы используем PagerDuty.

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

Хороший мониторинг, уведомления и дежурные специалисты? Деплойте в пятницу.

Вручную просматриваете логи через ssh? Ждите до понедельника.

Сколько времени уходит на решение проблем


Наконец, главный критерий — сколько времени займёт исправление проблем. Это отчасти зависит от «радиуса поражения» вносимых изменений. Даже если у вас вылизанный конвейер деплоя, некоторые изменения трудно быстро исправить. Откат изменений в системе извлечения данных и в схеме поискового индекса может потребовать трудоемкого переиндексирования, помимо исправления какой-то строчки кода. Средняя длительность деплоя, проверки, исправления и переразвёртывания изменений в CSS может составлять минуты, в то время как серьёзные изменения в хранилище могут потребовать дней работы.

Для всех работ в рамках конвейера деплоя, которые на макроуровне могут повысить надёжность внесения изменений, никакие изменения не являются одинаковыми, поэтому нужно оценивать их по отдельности. Если что-то пойдёт не так, мы сможем всё быстро исправить?

Полностью исправляется с помощью одного восстанавливающего коммита? Деплойте в пятницу.

Возможны большие затруднения, если что-то пойдёт не так? Ждите до понедельника.

Думайте сами, решайте сами


Какова моя позиция по #NoDeployFriday? Я считаю, что всё зависит от релиза. Изменения с маленьким «радиусом поражения», которые легко откатить, можно деплоить в любое время в любой день. При больших изменениях, влияние которых нужно внимательно отслеживать в production-системе, я очень рекомендую подождать до понедельника.

По сути, это вам решать, деплоить ли по пятницам. Если вы работаете со скрипучей и хрупкой системой, то лучше избегать пятниц, пока не сделаете всё необходимое, чтобы улучшить процесс деплоя. Только обязательно это сделайте, не отмахивайтесь. Отказ от пятничных релизов — это нормальный способ прикрыть временные недоработки в инфраструктуре. Это разумное снижение ущерба ради блага бизнеса. Но плохо, если это правило прикрывает постоянные недоработки.

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

Успешного деплоя.

© Habrahabr.ru