Нужно ли запрещать деплоить в production в определённое время? Или движение #NoDeployFriday стало реликтом времён, когда не было всеобъемлющих интеграционных тестов и непрерывного деплоймента?
В своей команде вы могли столкнуться с той же самой дилеммой. Кто прав, а кто виноват? Является ли отказ от деплоя по пятницам разумной стратегией снижения рисков, или это вредная культура, мешающая нам создавать более качественные и устойчивые системы?
Динь-динь
Уверен, что инженеры, имевшие счастье быть «на связи», лишались выходных из-за всё сломавших пятничных изменений. Я тоже был в такой ситуации. Телефонный звонок во время выхода с семьёй или посреди ночи, уведомляющий о падении приложения. После того, как залезешь в компьютер и проверишь быстро растущие логи, становится очевидно, что всё порушило редкое необработанное исключение. Отвратительно.
В ходе анализа выясняется, что для сценария, который привёл к сбою, не были написаны тесты, видимо, потому что это не посчитали вероятным. После ряда длительных созвонов с другими инженерами в поисках лучшего способа откатить изменения и всё исправить, система снова начинает работать. Фух.
В понедельник проводится встреча «пять почему».
"Давайте просто прекратим деплоить по пятницам. Тогда на выходных всё будет стабильно работать, а на следующей неделе мы будем начеку после всевозможных релизов".
Все кивают. Если что-то не уходит в эксплуатацию до полудня четверга, то оно ждёт до утра понедельника. Такой подход вредит или помогает?
Как вы знаете, высказывания в Твиттере часто очень субъективны. Хотя запрет пятничных релизов выглядит разумным, кто-то быстро укажет, что это просто костыль из-за хрупкости платформы, причина которой в плохих процессах тестирования и деплоя.
Некоторые даже предполагают, что вам просто больше нравится спокойное развёртывание, чем сами выходные:
Другие пользователи полагают, что возможным решением проблемы может быть внедрение флагов функций.
Этот пользователь считает, что проблемы рискованного деплоя не должно возникать благодаря доступным нам сегодня процессами и инструментам.
Кто принимает решения?
Весь этот обмен мнениями свидетельствует о том, что мы, как сообщество инженеров, можем сильно расходиться во мнениях и не обязательно соглашаться друг с другом. Кто бы мог подумать. Вероятно, эта ситуация также демонстрирует, что общая картина с #NoDeployFriday содержит такие нюансы, которые не слишком хорошо отражены в Твиттере. Верно ли, что мы все должны применять непрерывный деплоймент, а иначе «делаем неправильно»?
В принятии подобного решения есть психологический аспект. Неприязнь к пятничным релизам происходит из страха сделать в течение недели ошибки (из-за усталости или спешки), которые могут навредить, пока большинство сотрудников два дня отдыхают. В результате пятничный коммит, содержащий потенциальную проблему, может испортить выходные куче народу: дежурным инженерам, другим инженерам, которые будут удалённо помогать решать проблему, а возможно и специалистам по инфраструктуре, которым придётся восстанавливать повреждённые данные. Если сбой окажется серьёзным, то в ситуацию могут быть вовлечены и другие сотрудники компании, которым нужно будет связываться с клиентами и минимизировать ущерб.
Заняв позицию идеалиста, можно предположить, что в идеальном мире с идеальным кодом, идеальным покрытием тестами и идеальным QA никакие изменения не смогут привести к проблеме. Но мы люди, а людям свойственно ошибаться. Всегда будут какие-то странные пограничные случаи, которые не закрыты при разработке. Это жизнь. Так что движение #NoDeployFriday имеет смысл, хотя бы теоретически. Однако это лишь слепой инструмент. Я считаю, что оценивать сделанные изменения нужно в зависимости от ситуации, и априори нужно исходить из того, что мы деплоим в любой день, даже по пятницам, но при этом должны иметь возможность изолировать те изменения, которые должны подождать до понедельника.
Есть некоторые вопросы, которые мы можем обсудить. Я поделил их на категории:
- Понимание «радиуса поражения» изменения.
- Продуманность процесса деплоя.
- Способность автоматически определять ошибки.
- Сколько времени уходит на решение проблем.
Теперь давайте обсудим.
Понимание «радиуса поражения»
Когда в онлайне опять начинают ломать копья про пятничные релизы, всегда забывают о важном — о самой природе изменений. Не бывает одинаковых изменений в кодовой базе. Одни коммиты немного правят интерфейс и ничего более; другие рефакторят сотни классов, не затрагивая функциональность программы; третьи меняют схемы базы данных и вносят серьёзные изменения в процесс потребления данных в реальном времени; четвёртые могут перезапустить один экземпляр, в то время как пятые способны инициировать каскадный перезапуск всевозможных сервисов.
Глядя на код, инженеры должны хорошо представлять «радиус поражения» вносимых изменений. Какая часть кода и приложения будет подвержена влиянию? Что может упасть, если новый код будет сбоить? Это всего лишь клик по кнопке, который выкинет ошибку, или будут потеряны все новые записи? Изменение вносится в один изолированный сервис, или синхронно поменяются многие сервисы и зависимости?
Не представляю, кто будет отказываться вносить изменения с небольшим «радиусом поражения» и простым деплоем в любой день недели. Но при этом внесение крупных изменений — особенно, связанных с инфраструктурой хранилищ, — должно проводиться осторожнее, возможно, в то время, когда в онлайне находится меньше всего пользователей. Будет ещё лучше, если такие масштабные изменения запускать в эксплуатацию параллельно, чтобы протестировать и оценить их работу при реальной нагрузке, и никто об этом даже не узнает.
Здесь нужно принимать решения в зависимости от ситуации. Каждый ли инженер осознаёт «радиус поражения» изменений в production-среде, а не только в среде разработки? Если нет, то почему? Можно ли улучшить документацию, обучение и отображение влияния изменений кода в production?
«Радиус поражения» маленький? Запускайте в пятницу.
«Радиус поражения» большой? Ждите до понедельника.
Продуманность процесса деплоя
Один из способов снижения рисков заключается в непрерывном совершенствовании процесса деплоя. Если для запуска свежей версии приложения всё ещё необходимо, чтобы специалист знал, какой нужно запустить скрипт, какой файл и куда скопировать, то пора плотно заняться автоматизацией. За последние годы инструментарий в этой сфере шагнул далеко вперёд. Мы часто используем Jenkins Pipeline и Concourse, они позволяют прямо кодом задавать конвейеры сборки, тестирования и деплоя.
Процесс полной автоматизации развёртывания — вещь интересная. Он позволяет вам отступить назад и попробовать абстрагировать то, что должно произойти с момента инициализации pull request до отправки приложения в эксплуатацию. Описание всех шагов в коде, например, в упомянутых выше инструментах, поможет вам обобщить определения шагов и повторно использовать их во всех приложениях. К тому же вам будет интересно отметить некоторые странные или ленивые решения, которые вы когда-то приняли и с которыми смирились.
Каждому инженеру, который прочитал предыдущие два параграфа и отреагировал в стиле «Ну конечно! Мы это делаем годами!» я могу гарантировать, что ещё 9 других представили свою инфраструктуру приложения и скривились, осознав объём работы, который нужно проделать для перевода системы на современный конвейер деплоя. Это подразумевает использование преимуществ современных инструментов, которые не только выполняют непрерывную интеграцию, но и позволяют непрерывно поставлять баги в прод, причём инженерам достаточно нажать кнопку для ввода в эксплуатацию (или вообще делать это автоматически, если вы достаточно смелы).
Совершенствование конвейера деплоя требует вовлечённости и соответствующего персонала — это точно не побочный проект. Хорошим решением будет выделить команду для улучшения внутреннего инструментария. Если они ещё не знают о существующих проблемах — а они наверняка знают, — то можно собрать информацию по самым болезненным ситуациям, связанным с процессом релиза, затем приоритезировать и совместно с другими заняться исправлением. Медленно, но верно положение будет улучшаться: код станет отправляться в эксплуатацию быстрее и с меньшим количеством проблем. Всё больше людей смогут изучать лучшие подходы и самостоятельно вносить улучшения. По мере выправления ситуации, подходы будут распространяться в командах, и этот новый проект будет завершён правильно, без привычного копирования старых дурных привычек.
С момента мерджа pull request’а до внесения коммита должен быть автоматизирован настолько, чтобы вам даже не нужно было думать об этом. Это не только помогает изолировать реальные проблемы в QA, потому что единственной переменной является изменённый код, но делает написание кода куда более приятным делом. Введение в эксплуатацию децентрализуется, что повышает личную автономность и ответственность. А это, в свою очередь, приводит к более обдуманным решениям относительно того, когда и как выкатывать новый код.
Надёжный конвейер деплоя? Выкатывайте в пятницу.
Вручную копируете скрипты? Ждите до понедельника.
Способность определять ошибки
Введение в эксплуатацию не останавливается после того, как код начал работать. Если что-то идёт не так, нам нужно знать об этом, и желательно, чтобы нам об этом сообщали, а не приходилось выискивать информацию самостоятельно. Для этого нужно автоматическое сканирование логов приложений на ошибки, явное отслеживание ключевых метрик (например, количество обработанных сообщений в секунду, или доля ошибок), а также система предупреждения, сообщающая инженерам о возникновении критических проблем и демонстрирующая негативную тенденцию по определённым метрикам.
Эксплуатация всегда отличается от разработки, и инженерам нужно отслеживать работу определённых частей системы. Нужно отвечать на вопросы о каждом последующем изменении: оно ускорило или замедлило систему? Таймаутов стало больше или меньше? Мы ограничены по процессору или по вводу/выводу?
Данные по метрикам и ошибкам должны передаваться в систему предупреждения. У команд должна быть возможность определять, какие сигналы свидетельствуют о негативной ситуации, и рассылать автоматические сообщения об этом. Для наших команд и самых серьёзных инцидентов мы используем PagerDuty.
Измерение метрик production-системы означает, что инженеры смогут увидеть, если что-то изменилось после каждого деплоя, к лучшему или к худшему. И в самых плохих случаях система автоматически сообщит кому-то о возникшей проблеме.
Хороший мониторинг, уведомления и дежурные специалисты? Деплойте в пятницу.
Вручную просматриваете логи через ssh? Ждите до понедельника.
Сколько времени уходит на решение проблем
Наконец, главный критерий — сколько времени займёт исправление проблем. Это отчасти зависит от «радиуса поражения» вносимых изменений. Даже если у вас вылизанный конвейер деплоя, некоторые изменения трудно быстро исправить. Откат изменений в системе извлечения данных и в схеме поискового индекса может потребовать трудоемкого переиндексирования, помимо исправления какой-то строчки кода. Средняя длительность деплоя, проверки, исправления и переразвёртывания изменений в CSS может составлять минуты, в то время как серьёзные изменения в хранилище могут потребовать дней работы.
Для всех работ в рамках конвейера деплоя, которые на макроуровне могут повысить надёжность внесения изменений, никакие изменения не являются одинаковыми, поэтому нужно оценивать их по отдельности. Если что-то пойдёт не так, мы сможем всё быстро исправить?
Полностью исправляется с помощью одного восстанавливающего коммита? Деплойте в пятницу.
Возможны большие затруднения, если что-то пойдёт не так? Ждите до понедельника.
Думайте сами, решайте сами
Какова моя позиция по #NoDeployFriday? Я считаю, что всё зависит от релиза. Изменения с маленьким «радиусом поражения», которые легко откатить, можно деплоить в любое время в любой день. При больших изменениях, влияние которых нужно внимательно отслеживать в production-системе, я очень рекомендую подождать до понедельника.
По сути, это вам решать, деплоить ли по пятницам. Если вы работаете со скрипучей и хрупкой системой, то лучше избегать пятниц, пока не сделаете всё необходимое, чтобы улучшить процесс деплоя. Только обязательно это сделайте, не отмахивайтесь. Отказ от пятничных релизов — это нормальный способ прикрыть временные недоработки в инфраструктуре. Это разумное снижение ущерба ради блага бизнеса. Но плохо, если это правило прикрывает постоянные недоработки.
Если вы не уверены в том, какой эффект окажут изменения, то отложите до понедельника. Но подумайте, что можно сделать в следующий раз, чтобы лучше представлять себе этот эффект, и улучшите для этого сопутствующую инфраструктуру. Как и всегда в жизни, у каждого решения есть свои нюансы. Решения не делятся на «чёрное» и «белое», на «правильное» и «неправильное»: пока мы делаем всё что можем для бизнеса, приложений и друг друга, улучшая свои системы, значит мы всё делаем хорошо.
Успешного деплоя.
Комментарии (14)
cross_join
05.06.2019 15:27Не увидел критерия критичности системы, только «радиус поражения».
В мире есть много систем, которые спокойно пролежат до понедельника (тотальное поражение).
Похоже, не раскрыты темы «Можно ли развертывать в пятницу 13-го?» и «Можно ли развертывать в субботу (чтобы не прерывать цикл)?»
Вера в инструменты, в номер текущего года и в тесты задорно-заразительная, конечно.
dss_kalika
05.06.2019 17:17+1Проблема в том, что даже небольшое, некритичное, косметическое, внесённое в вообще не связанную систему изменение может случайно сломать что то важное.
Забить очередь, вызвать проблему разворачивания, сломать вёрстку, открыть цикл без выхода, сделать удаление объекта с тысячами связей итп-итп.
И сколько от этого не защищайся — оно всегда может вылезти.
Так что, от греха подальше, не надо деплоить в пятницу, если в этом нет особой необходимости (требует бизнес).
Lpndn
05.06.2019 22:54+1Меня, наверное, за такие еретические мысли закидают хабротапками, но всё же:
почему никто не учитывает версию, что обновление продакшна в понедельник опасно для бизнеса чуть более, чем полностью? Почему важнее без эксцессов провести выходные, а потом посреди недели положить прод и чинить его, в то время как сервисы будет недоступны и бизнес будет нести убытки?
Разумеется, бизнес должен оплачивать такие работы, а для этого ИТ должен объяснить, зачем это нужно и почему это важно.
Здоровье, конечно же, важнее всего, и отдыхать нужно всем, но если глобальные сбои и падения войдут в систему, то не?куда будет возвращаться с выходных. Разве не лучше сделать всё в период минимальной нагрузки и вовлечённости пользователей, когда можно спокойно исправить все вылезшие баги, прогнать все тесты, а если что-то упадёт – поднять, опять же без паники и потока тикетов?adictive_max
06.06.2019 05:29Почему важнее без эксцессов провести выходные, а потом посреди недели положить прод и чинить его, в то время как сервисы будет недоступны и бизнес будет нести убытки?
Потому что сама проблема «не деплой перед выходными» — она про то, чтобы не создавать внезапную сверхурочную работу. Если бизнесу сильно критично, он может запланировать обновление на выходные, и тогда никакой проблемы не будет.Lpndn
06.06.2019 11:55Мне кажется, что не бизнес должен планировать обновления, а ИТ, исходя из общих целей
dss_kalika
06.06.2019 10:17Проблема в том, что есть много систем, которые должны работать в выходные, а не только посреди недели. Но, если посреди недели люди работают — следят за системой, с клиентской стороны готовы что то исправить, перезалить или ещё как то отреагировать, то в выходные всё это намного менее контролируемо, а потому — должно быть стабильно.
Тут была где то прекрасная история о том как у «админа» отвалилась удалёнка в выходные, когда всё легло, а охрана не пустила в офис, потому что «выходной, не положено». Это как пример нештатного эксцесса в выходной )
tangro
06.06.2019 13:58Не понимаю этих предрассудков. Откладывание деплоя на 3 дня — это 3 дня для юзеров без потенциально пофигшенных багов или новых фич. Если, условно, релизить результаты по результатам двухнедельных скрамов и каждый раз откладывать релиз на 3 дня, то за год у вас будет 52/2*3 = 78 дней пауз в релизах из-за ваших страхов и предрассудков. А у ваших конкурентов — не будет. И они вырвутся вперёд.
Нужно выйти что-то экстренно поднять в субботу? Ну и отлично! Оплата по ставке 2х, такси на работу и назад, дополнительный отгул — и я легко выйду. Тем более, что понадобится это аж 2-3 раза в год. Копеечные затраты для бизнеса. Всех бы проблем.
Peter03
06.06.2019 17:43Если overtime оплачивается с коэффициентом выходной *2, ночью еще *2. То надо деплоится в пятницу 23:55, the best bung for the buck.
APXEOLOG
А программисты не должны допускать багов. Ожидания и реальность редко соотносятся
Что касается деплоя по пятницам — тут нужно смотреть с точки зрения пользователей. Если пользователям важен деплой именно в пятницу — значит нужно поступать так (и строить свои процессы соответственно). Пример: Path of Exile запускает новые лиги в пятницу вечером, чтобы игроки могли играть все выходные не отвлекаясь на работу
Если пользователям это не нужно — лучше деплоить в понедельник. Пример: Вы делаете какой-то бизнес продукт и ваши пользователи в массе своей пользуются им только в рабочие дни. Какой смысл делать релиз в пятницу, если это не приносит никакой пользы и повышает риски?
zharikovpro
> Если пользователям важен деплой именно в пятницу — значит нужно поступать так
Пользователям не нужны деплои, пользователям нужны фичи. Если лиги запускаются в пятницу, это не значит что в пятницу вообще был какой-то деплой.
> Пример: Path of Exile запускает новые лиги в пятницу вечером, чтобы игроки могли играть все выходные не отвлекаясь на работу
Как вариант — задеплоить фичу на неделе, протестировать на избранны пользователях в stealth режиме, а в пятницу включить ее для всех с помощью feature toggle.
APXEOLOG
А если в feature toggle будет ошибка? :)
zharikovpro
То это вероятно станет известно раньше. Feature toggles нужно тестировать тщательно, и конечно заранее. Но тут в общем такая же история как и с другими багами. Невозможно защититься от обнаружения багов в пятницу. Но можно хотя бы не деплоить новые баги в пятницу.