В первом квартале 2021 года Storytel сделал большой шаг вперед в мобильных метриках DORA (частота деплоя, время до попадания коммита в прод, процент деплой, вызывающих сбои в проде, время до восстановления от таких сбоев). Мы преобразовали наши внутренние процессы и нашли инновационный способ сократить цикл выпуска приложений с трех недель до одной, не сводя с ума наших инженеров. Ниже я хочу поделиться некоторыми из наших знаний — и да, некоторыми проблемами. И, конечно же, мы еще не закончили, в последнем разделе мы поделимся некоторыми идеями и идеалистическими планами относительно того, куда пойдет Storytel дальше.
Как все начиналось
Давным-давно, на заре Storytel, релизы его мобильных приложений происходили «спонтанно». Как и большинство стартапов на раннем этапе, команда просто выпускала продукт всякий раз, когда чувствовала, что может предложить пользователям что-то важное, будь то новая функция или важное исправление ошибки. Это могло случаться часто или редко, но всякий раз, когда это происходило, оно сопровождалось всплеском активности: тестирование, исправление, стресс, паника. Это было ближе к концу 2018 года, когда мы перешли к подходу «релизного поезда», выпуская релизы каждые 3 недели, независимо от того, нуждались мы в этом или нет. Это добавило много необходимой структуры и предсказуемости и в целом было расценено как очень положительное изменение.
А потом… В основном ничего не происходило. В течение долгого времени. Несмотря на то, что мы знали, что это не очень хороший каденс, мы глубоко провалились в ловушку «достаточно хорошего». Это не было ужасно, и это в основном работало на нас. И несмотря на то, что уже в 2019 году мы заявляли о стремлении улучшить ситуацию, мы так и не сделали для этого ничего особенного и не взяли на себя никаких конкретных обязательств в отношении будущих инвестиций. Все это время наши процессы (как в техническом отделе, так и за его пределами) синхронизировали свой танец с «битом Storytel», продиктованным релизами мобильных приложений, что сделало это аксиомой. Чувствовалось, что с каждым кварталом менять его будет все труднее.
Конвейеры
Это та часть, где я говорю вам, что отпуск и отключение действительно важны. Это клише, но это правда. Позвольте мне нарисовать вам картину: сейчас ноябрь 2021 года, я наслаждаюсь длинными выходными в спа-центре. Я ношу дурацкое кимоно, посещаю один из этих сеансов групповой релаксации, и все же у меня на уме рабочие вопросы. И пока я блуждал туда-сюда, каким-то образом мой разум наткнулся на лайфхак, который ученые-компьютерщики использовали по крайней мере с 1985 года для решения проблем, находящихся вне их досягаемости: конвейеры!
Лежа там в безумном кимоно, я понял: вместо того, чтобы тяжело бороться за сокращение наших многочисленных процессов, связанных с релизами, увеличивая давление времени и заставляя всех нервничать, мне просто нужно было, чтобы у нас одновременно было больше непрерывных процессов выпуска. Таким образом, мы можем эффективно создавать еженедельные релизы без каких-либо существенных изменений в наших процессах. Конечно, хотелось надеяться, что со временем процессы станут легче, эффективнее, упорядоченнее и в целом лучше, но ключевой вывод заключался в том, что все это не обязательно должно происходить заранее. Нам не нужно ждать.
Процесс релиза в то время занимал 3 недели и состоял примерно из 3 этапов, поэтому его было легко набросать в виде 3-этапного пайплайна.
- Этап 1: «Заморозка»: мы отделяемся от ветки разработки, создаем новый релиз-кандидат (RC) и запускаем на нем процесс контроля качества. Код входит в этап «заморозки», когда принимаются только утвержденные изменения, связанные с качеством. Это занимает около недели.
- Стадия 2: «Бета»: RC в настоящее время считается в основном стабильным и вступает в период «Бета». Это предполагает предоставление его широкой аудитории, включая внешних пользователей бета-версии. Основное внимание на этом этапе уделяется мониторингу. Если обнаружены некоторые действительно критические проблемы, изменения в код все же можно внести, но цель состоит в том, чтобы избежать дальнейших изменений. На этом этапе мы официально отправляем RC на окончательную проверку в магазины Apple/Google.
- Этап 3: «Развертывание»: Мы используем постепенное развертывание и держим палец на кнопке «Прервать» в случае серьезных плохих новостей, поступающих от Crashlytics или службы поддержки. Этот этап не особо трудоемкий, но может быть очень эффективным, потенциально избавляя от многих хлопот многих пользователей и службу поддержки клиентов. Обычно это занимает большую часть рабочей недели, при этом развертывание завершается на 100% не позднее пятницы.
Проект “Турбонаддув”
Проект “Турбонаддув” (Turbocharge) ставил перед собой цель — позволить выполнять эти процессы параллельно, а не последовательно, и не стремиться изменить или улучшить какой-либо из этапов. К моменту завершения проекта у нас будет по одному релиз-кандидату на каждой фазе каждую неделю, всего 3 параллельных релиз-кандидата.
Чтобы это произошло, я довольно много занимался продвижением и “продажей” этой идеи, и самым важным моим открытием было то, что аналогии играют ключевую роль. Даже очень технических сотрудников было трудно переключить в мышление “конвейера”. Я внимательно следил за тем, чтобы всегда быть уважительным, и обнаружил, что устоявшаяся аналогия «9 пар не могут родить ребенка за 1 месяц, но они могут родить 9 детей за 9 месяцев» была полезной для многих, даже если она может быть неудобной для рабочей обстановки.
Я взял один из моих любимых инструментов: я написал RFC для всего нашего технического сообщества. Я поделился документом, в котором четко указывалось, как я хочу, чтобы наш процесс релиза выглядел, каковы его преимущества и недостатки. Я довольно долго собирал отзывы о нем, давая возможность каждому собраться с мыслями и внести предложения. В конце концов, большая часть отзывов, которые я получил, была положительной, а большую часть остальных можно было бы обозначить как «похоже, мне предстоит больше работать». Остальное я смог решить, так что в целом после этого этапа я был совершенно уверен, что не было никаких реальных, больших, сложных технических проблем, которые помешали бы нам начать действовать в соответствии с планом.
Начинаем
В этот момент истории наступают зимние каникулы, поэтому я дал последний совет всем подумать об этом на каникулах. Как только мы вернулись в январе, я нажал на курок: мы собираемся сделать это, и мы собираемся сделать это к концу первого квартала.
Возможно, это кажется радикальным, но я твердо верю в закон Паркинсона: работа расширяется, чтобы заполнить время, доступное для ее завершения. Поэтому, приводя этот план в действие, я удачно использовал одну из своих любимых цитат:
Признаюсь, я не был по-настоящему уверен, что такие большие изменения в наших методах работы действительно могут быть достигнуты в течение одного квартала. Но я был уверен, что этого не произойдет, если я не буду смелым и не поставлю большие цели.
Несмотря на то, что команды разработчиков проделали большую работу, чтобы это произошло (в основном в рамках усилий по автоматизации и написания сценариев для нашей CI/CD), я много думал о том, как мы могли бы на самом деле сделать это, когда придет время. Когда, наконец, пришло озарение, все оказалось так просто, как можно было бы надеяться. Это конвейер, и есть только один способ запустить его:
вы вставляете первый элемент, а затем следующий — по истечении точного времени, которое соответствует пропускной способности, которую вы ожидаете увидеть на другом конце.
Турбо-выпуски
Внезапно 7 недель, которые мы отвели на подготовку, истекли, и пришло время начать заполнение конвейера. Как и следовало ожидать, несмотря на все мои усилия сделать все понятным и заблаговременно объяснить план, когда мы действительно начали, многие люди были удивлены. Я слышал много «О, это на этой неделе?», «О, я неправильно это понял» и мое любимое «О, я читал расписание задом наперед». Когда дело доходит до общения, определенно есть чему поучиться, но…
В конце концов это сработало! 21 и 28 марта были нашими первыми «турбо-выпусками» с перерывом всего в неделю. С тех пор мы работаем в том же ритме, замораживая код каждую пятницу и начиная раскатывание релиза каждый понедельник. 31 релиз на момент написания этой статьи!
Однако история на этом не заканчивается. Я думаю, важно помнить, что внесение изменений в любой установленный процесс также принесет некоторые краткосрочные негативные последствия: будет неразбериха, ошибки, и многие уроки будут усвоены на собственном горьком опыте. Все это необходимо, прежде чем организация сможет ощутить преимущества нового процесса. Как назло, именно в это время я узнал, что для этого есть термин: «Кривая J».
Один из основных принципов нашей новой стратегии доставки заключался в том, что при возникновении проблемы мы больше не сосредотачиваемся на устранении проблемы в текущей версии и развертывании исправления (т. е. никаких «горячих исправлений»). Вместо этого мы прерываем текущее развертывание и убеждаемся, что мы исправим ошибку в следующей версии. Это очень важно, так как это прерывает цикл отрицательной обратной связи, с которым мы часто сталкивались ранее, когда разработчикам и тестировщикам нужно было сосредоточиться на текущем проблемном выпуске, не тратя свое время на следующий выпуск, что делает еще более вероятным, что следующий выпуск также будет быть проблематичным в той или иной мере.
Вскоре нам пришлось проверить, хорош ли новый принцип только на бумаге или он работает и на практике? В нашем 6-м «турбо-релизе» мы столкнулись с нетривиальным сбоем в процессе регистрации на iOS, и мы не могли исправить это, просто настроив фиче-флаг. Мы сохраняли хладнокровие и следовали плану: мы остановили текущее развертывание и исправили проблему в выпуске на следующей неделе. Угадайте, что? Это сработало! Следующий выпуск был успешным, и нам удалось объяснить отсутствие исправления внутренним заинтересованным сторонам, хотя это означало, что некоторым пользователям пришлось ждать дольше или изменить бизнес-планы.
Подводя итог, вот краткий список преимуществ, которые мы видим с конвейерами сейчас, после того как мы жили этой мечтой в течение полных шести лет:
- Более частые обновления для пользователей.
- Меньший риск, связанный с развертыванием кода мобильного приложения в рабочей среде.
- Никаких исправлений, что приводит к гораздо меньшему объему быстрой «специальной» работы, что делает работу более предсказуемой и стабильной для всех, кто работает с мобильными приложениями в той или иной степени.
- Больше гибкости при планировании, проверке и экспериментировании для продакт-менеджеров и продуктовых команд.
Что дальше
Конечно, мы не считаем путешествие завершенным. Это вершина постоянного совершенствования, мы не хотим останавливаться на достигнутом. Мы не хотим снова оказаться в ловушке “достаточно хорошего”. Теперь, проработав с этой системой более 6 месяцев, мы оказались на «правильной стороне J-кривой». Мы надеемся, что будущие улучшения коснутся двух основных областей:
- Получения еще больше пользы от нашей программы тестирования, распространения ежедневных сборок из ветки разработки среди широкой внутренней аудитории. Мы стремимся еще больше увеличить ценность, которую мы получаем от этого, еще лучше и быстрее сортируя поступающие отзывы.
- Сокращения периода стабилизации: наличие меньшего количества одновременных релиз-кандидатов, что упрощает и еще больше сокращает время выхода на рынок.