ОРГАНИЗАЦИЯ КОМАНДНОЙ РАБОТЫ

Главная цель организации командной работы — сделать работу всех команд прозрачной и предсказуемой для заказчиков: от менеджера проекта до руководителя продукта и, конечно, для других команд. А тем самым — добиться от них непрерывного приращения продукта новым кодом, ценным для клиентов.
В результате команды становятся «атомарными», самостоятельно решая, каким путём достигать поставленных целей. Они понимают, что главное — держать слово, выполнять все обещанные задачи. И тогда заказчик, доверяя им, не станет отвлекать сотрудников команд вопросами по статусу задач. Если работа организована правильно, команда без «кнута» непрерывно улучшает свою деятельность и заботится о комфортной атмосфере для каждого её участника.
Первый шаг в организации командной работы — научить команды каждый спринт делать задачи до конца, готовыми к выпуску, так, чтобы мощность команды была стабильна и предсказуема. Команды должны научиться:
  • держать слово, чтобы заказчики только ставили задачи при планировании спринта и принимали их на демонстрации, не вмешиваясь в повседневную работу команды;
  • оценивать задачи через типовые работы;
  • реализовывать типовые работы согласно нормативной оценке.
Со временем команды должны последовательно увеличивать объём выполняемых в течение спринта типовых нормированных работ до 70% от своей максимальной мощности, доведя фокус-фактор до значения 0,7.
Для достижения результата команды должны научиться сознательно выполнять все процессы спринтов, понимая причинно-следственные связи своих действий.

Планирование и старт

При планировании спринта:
  • устанавливаются цели спринта;
  • включаются задачи по улучшению продукта из общего списка задач;
  • планируются работы по реализации взятых в спринт задач.
Команда берёт на себя обязательство — реализовать набор задач по улучшению продукта в течение спринта, исходя из своей максимальной мощности и фокус-фактора. Допустим, она состоит из 10 человек и планирует спринт на 10 дней, или 80 часов. Тогда максимальный объём задач, которые можно взять в спринт (при фокус-факторе 0,7), укладывается в 560 часов. Все задачи должны быть предварительно разложены на типовые работы и оценены согласно нормативам. Очень важно, чтобы команда уже в ходе планирования спринта хорошо понимала суть принимаемых задач, критерии приёмки заказчиками и получила ответы на все свои вопросы. Заказчиками спринта могут быть владелец продукта, менеджеры проектов, сотрудники смежных команд и другие.
Если использовать в качестве метафоры приготовление ужина, команда должна хорошо понимать меню, убедиться, что все ингредиенты в наличии, и быть уверенной, что есть «повара», способные вкусно и быстро приготовить все блюда. Рекомендую использовать здесь практику, применяемую в управлении при постановке задач: «повтори, как ты понял задачу». Каждый член команды рассказывает остальным, в чём заключается взятая им задача, из каких типовых работ она состоит, что он планирует по ней делать и какого результата предполагает достигнуть. Если возникают вопросы, на них помогают ответить все члены команды. Иначе говоря, уже на этапе планирования спринта команда должна быть уверена, что справится со всеми взятыми на себя задачами.

ОРГАНИЗАЦИЯ КОМАНДНОЙ РАБОТЫ

Для достижения результата команды должны научиться сознательно выполнять все процессы спринтов, понимая причинно-следственные связи своих действий.
Бывает, команда берёт в спринт задачи, превышающие её мощность. В этом случае есть риск, что она не успеет или придётся работать сверх нормы. Команда должна явно проинформировать заказчика, как она с этим справится. Если же объём и характер задач меньше мощности команды, всё равно надо информировать заказчика, как она намерена распределить избыток ресурсов.
Невероятно важно, чтобы планирование спринта закончилось с хорошими чувствами всех участников — и команды, и заказчиков. Чтобы не было ощущения, будто кто-то кого-то продавил. Планирование спринта — не соревнование между командой и заказчиками за первенство. При таком подходе проиграют обе стороны, и, скорее всего, цели спринта не будут достигнуты.
Есть и иные неконструктивные модели поведения:
  • команда занимает позицию — «уговорите меня что-нибудь сделать»;
  • команда безропотно берёт в спринт всё, что скажет заказчик;
  • заказчик занимает позицию — «вы будете делать всё, что прикажу, даже вне зоны вашей ответственности».
Полагаю, не стоит специально объяснять, почему перечисленные варианты взаимодействия не пойдут во благо. А вот для того, чтобы встречи проходили в дружественной и продуктивной атмосфере, необходимо заранее договориться о прозрачных критериях приёмки задач в спринт. У всех участников должны сформироваться сходные ожидания. По сути, к планированию стоит приступать с позитивным, оптимистическим посылом («всё у нас получится»), а сама встреча лишь фиксирует договорённости. Например, задачи надо предварительно разложить на типовые работы и оценить по нормативам. В рамках критериев приёмки должно быть запрещено брать в спринт задачи, о сути которых до его начала ничего не известно.
Главная цель планирования спринта в том, чтобы команда и заказчики одинаково понимали цель спринта, а все задачи были гарантированно сделаны. Тогда спринт можно считать успешным.

Цели спринта и измеримость результата

Цели спринта побуждают команду работать совместно и обеспечивают гибкость в выборе средств достижения. Они устанавливаются при планировании и должны отражать потребность заказчика. Что он хочет достичь? Зачем ему именно эти задачи и именно в этом спринте? То есть заказчик при постановке целей команде должен дать информацию по проекту, в котором предполагается использовать результаты спринта. Рассказать, каким образом в проекте планируется их использовать, и дать своё видение того, как эти результаты влияют на будущее проекта. Это особенно важно, когда команда одновременно разрабатывает продукт для нескольких проектов. Так формируется сопричастность команды чему-то более глобальному и важному, нежели простое кодирование задач. А значит, существенно повышается мотивация участников на успех.
Грамотно ставить цели команде и информировать о проекте — это тоже навык, которому нужно учить клиентов. Заказчик, постоянно находясь в контексте своего проекта, может ошибочно считать, будто все вокруг так же хорошо информированы о ходе проекта. Но ведь это не так. Рекомендую разработать скрипт: какую минимально необходимую информацию должен выдать заказчик при каждом планировании, в котором участвует. Важно, чтобы информация о ходе проекта и влиянии на него конкретной команды доводилась при каждом планировании. Не один раз проинформировать и потом полгода ничего не говорить, а находить в себе силы делать это постоянно.
Цели должны быть понятны команде, а критерии её достижения — измеримы. Лучше избегать оценочных суждений, которые становятся причиной многих конфликтов.

ПЛАНИРОВАНИЕ СПРИНТА

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

Ежедневные встречи

Ежедневные 15-минутные встречи команды проводятся, чтобы контролировать прогресс в достижении целей спринта, адаптировать его задачи, выявлять препятствия. Такие встречи полезны для оперативного принятия необходимых решений.
Главная цель этих встреч — подтвердить, что все работы идут по плану и спринт будет выполнен успешно. На встрече проблемы и препятствия только выявляются, их решение выходит за её рамки. Иначе «15-минутка» затянется, а те, кого та или иная проблема непосредственно не касается, попросту потеряют время.
В незрелых командах часто возникает соблазн пропустить встречу или сократить их число до одной-двух в неделю, особенно, если, по мнению участников, всё идёт хорошо. Это не вариант. Встречи должны быть ежедневными, это дисциплинирует каждого участника. Знание того, что тебя перед лицом всей команды обязательно спросят, сделал ли ты, что планировал вчера, или нет, оказывает серьёзное психологическое давление. Почувствуйте разницу: одно дело, когда ты что-то не сделал для себя, и совсем другое, если подводишь свою команду. Практика показывает, что лишь немногие люди могут планировать свою деятельность больше, чем на день, и справиться с этим планом. Абсолютное большинство может планировать только один день вперёд и справляться с этим планом. Из этого и исходит назначение ежедневных встреч, где надо, во-первых, подтвердить выполнение дневного плана, а во-вторых, представить план на следующий день. Когда программист сказал, что выполнит свою задачу к завтрашнему дню, тестировщик будет готов подхватить эстафету. Но даже если сотрудник чувствует, что не справляется с задачей, всё равно разумнее поставить коллег в известность — они ведь могут подключиться к решению возникшей проблемы.
Кроме всего прочего, ежедневные встречи помогают команде постоянно находиться в едином информационном поле. Scrum-мастер фиксирует процент выполнения задач. Команда анализирует график сгорания задач на предмет отставания или опережения.

ЕЖЕДНЕВНЫЙ МИТИНГ

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

График сгорания задач и доска задач

График сгорания задач в простой форме показывает количество сделанной и оставшейся работы. По оси «X» отмечают дни спринта, по оси «Y» — нормированную трудоёмкость взятых в него задач, имеющих ценность. Типовой график сгорания задач содержит две линии: одна представляет собой линию идеальной работы, другая — фактическую, линию текущего состояния. Линия идеальной работы на рисунке окрашена зелёным цветом — прямая, соединяющая точку начала спринта, в которой есть полный объём работ, с точкой его окончания, где весь объём выполнен. На линию идеальной работы команда ориентируется для оценки опережения или отставания. Красная линия показывает оставшийся объём фактической работы в спринте. Команда опережает график, если линия фактической работы ниже идеальной, и отстаёт, когда красная линия выше зелёной.
Советую обогатить график дополнительными статистическими линиями, помогающими команде и заказчикам лучше понимать, насколько работа в текущем спринте отличается от обычной работы команды. Линия средней фактической работы, выделенная жёлтым цветом, показывает, как команда обычно справляется со спринтом (на основе статистики по предыдущим спринтам). Синяя линия средней фактической работы по успешно завершённым спринтам — как команда обычно выполняет успешный спринт (тоже на базе статистики предыдущих спринтов). Если линия фактической работы соответствует или ниже этой линии, команда с вероятностью 95% завершит спринт успешно, даже если она и выше идеальной. Фиолетовая линия — «безопасный коридор», показывающий вероятность успешного завершения спринта. Как свидетельствует опыт, если она будет пересечена линией фактической работы дважды, то спринт гарантированно будет неуспешен. Даже первое пересечение линии «безопасного коридора» говорит, что команде нужна помощь. Такие ситуации следует разбирать на ретроспективе.
Известно, что обычно выполнение задачи занимает более одного дня. Как же правильно учитывать частичное выполнение задачи в каждый день? Типовым решением можно считать оценочное суждение сотрудника о проценте выполненной работы. Есть и другой метод. Процент готовности задачи определяется автоматически на основе текущего состояния задачи и имеющихся на данный момент артефактов. Например, после завершения работы аналитика (оно определяется закрытием соответствующего блока и наличием технического задания) готовность задачи помечается как отношение трудоёмкости аналитической работы к общей трудоёмкости задачи. Аналогичный подход применяется для программиста и других ролей. До тех пор, пока программист не выложил код в репозиторий исходного кода, его трудозатраты при определении готовности задачи не учитываются.
Другим способом визуального представления предстоящей и проделанной работы является доска задач. Существует много её разновидностей, но главное — она должна отражать актуальное состояние каждой задачи, взятой в спринт.

График сгорания задач

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

Готовность задач к выпуску

Определение готовности — это, по сути, формальное описание состояния приращения продукта, соответствующего предъявляемым к продукту требованиям качества.
Можно ли считать задачу сделанной, когда код выложен в репозиторий исходного кода? Если не определены критерии готовности, незрелая команда вполне может так считать. Другими словами, критерии определения готовности — это соглашение между командой разработки и владельцем продукта о том, что принять в качестве минимальных критериев выполнения задачи. Строго говоря, сделанной считается задача, которую можно выпустить и развернуть на стендах заказчика, включая рабочий стенд. Если после реализации задачу нельзя развернуть на рабочем стенде, значит, она не готова и её нужно доделывать. Команда должна понимать: пока код не развёрнут на рабочем стенде заказчика, его не существует, а значит, команда работает «в стол». Поэтому в критерии готовности включают стандарты качества кода и требования процесса выпуска.
  • Код написан и выложен в репозиторий исходного кода.
  • Код имеет комментарии.
  • Код проверен другим программистом или наставником.
  • Код собирается и запускается без ошибок.
  • Есть unit-тесты, и они выполняются без ошибок.
  • Код перенесён в основную (master) ветку.
  • Выполнен процесс выпуска с применением CI/CD-конвейера и т. д.
Заказчик в ходе планирования спринта вправе задать дополнительные критерии определения готовности:
  • задача должна быть развёрнута и продемонстрирована на определённом проектном стенде;
  • задача должна быть сдана заказчику в определённую дату раньше плановой демонстрации и т. д.
Важно понимать, что выявление дополнительных критериев — ответственность команды, а не заказчика. Если, планируя спринт, команда их не выявила, при демонстрации могут быть проблемы со сдачей задачи заказчику, вплоть до того, что её просто не примут. Конечно, команда может свалить вину на заказчика, который не дал дополнительных условий приёмки. В этом случае заказчик уйдёт в плохих чувствах, и это может сказаться на его последующем отношении к команде. Я ещё раз обращаю внимание, что невероятно важно, чтобы любые встречи с заказчиками заканчивались с хорошими чувствами для всех участников.

Демонстрация результата

Обзор результатов спринта — одно из важнейших событий в жизни команды, которая таким образом демонстрирует заказчику реализованные задачи, соответствующие критериям готового к выпуску функционала. Надо учиться тому, как проводить эту встречу легко и буднично, без переносов даты и без экстремальных переработок. Незрелые команды проводят предварительные обзоры без заказчиков, чтобы подготовиться к основной демонстрации. По мне, так лучше это время использовать на создание дополнительных ценностей.
То, как команда проводит демонстрацию результатов своей работы, показывает её зрелость. Это должно быть, если хотите, представление! И важно знать и соблюдать основные критерии хорошей демонстрации:
  • нет переноса сроков демонстрации;
  • команда демонстрирует, что сделано как часть процесса, имеющего ценность для заказчика;
  • стенд предварительно настроен, и при демонстрации нет ошибок;
  • все демонстрируемые примеры осмысленны и привязаны к предметной области и проекту. Не используются случайные наборы, например, «тест1» или «qwerty»;
  • нет «лоскутной» демонстрации задач; все они связаны в общий сценарий;
  • демонстрация идёт от документации: надо показать, что заказчик и пользователь смогут повторить операции, используя документацию к продукту;
  • демонстрацию проводят несколько членов команды или даже весь коллектив;
  • все замечания фиксируются, озвучивается срок их устранения.

ДЕМОНСТРАЦИЯ РЕЗУЛЬТАТА

Команда должна быть готова демонстрировать текущий результат в любой момент, поэтому стенды, где идёт разработка и тестирование, надо поддерживать в таком состоянии, чтобы не стыдно было проводить показ.
Как и при планировании спринта, заказчики играют важную роль в такой встрече. Их роль не ограничивается положением «зрителя», которого развлекает команда. Заказчик должен принять работу, оценить результат выполнения целей спринта согласно критериям и дать качественную обратную связь команде. Оценка даётся открыто всей команде — ведь чтобы стать лучше, люди должны понимать, как отработали. Если заказчик полностью удовлетворён результатом, стоит, похвалив команду, рассказать, как он повлияет на ход проекта. Если же заказчик недоволен итогом работы, надо указать на ошибки и недоработки — открыто, но без лишних эмоций. Порой заказчики, чтобы не портить отношения с командой, замалчивают отрицательную обратную связь, оправдывая это тем, что «люди хорошие», «они же старались». Это неправильно. Заказчикам надо учиться давать отрицательную обратную связь, а исполнителям — её принимать. Если проблемы замалчивать, команде не на чем будет совершенствоваться.
Следует помнить, что демонстрация — неотъемлемая часть спринта, а не отдельное событие, к которому нужно специально готовиться. Вообще-то команда должна быть готова демонстрировать текущий результат в любой момент, поэтому стенды, где идёт разработка и тестирование, надо поддерживать в таком состоянии, чтобы не стыдно было проводить показ. Это как с поддержанием чистоты в доме. Если квартиру не убирать регулярно, перед приходом гостей придётся совершить чудо, и всё равно останутся какие-то огрехи. Если же вы привыкли держать дом в порядке, никакие гости, даже внезапные, вас не смутят.

Ретроспектива

Ретроспектива завершает спринт. Её цель — запланировать дальнейшие мероприятия для повышения эффективности и качества, включая соответствующие пункты в список задач следующего спринта.
Ретроспектива — это возможность для команды провести инспекцию и создать план улучшений в следующем спринте. Она помогает улучшить атмосферу внутри команды, даёт возможность для оперативных полезных изменений уже в следующем спринте. Бывает, незрелая команда, проведя несколько ретроспектив и не осознав их ценность, отказывается от них, считая время зря потраченным. Поэтому приходится учить команду искусству ретроспективы и помогать ей. Приведу типовой пример бессмысленной ретроспективы. Команда выявила проблему: мы плохо поработали в спринте. А в качестве «мероприятия» высказали благое пожелание: давайте в следующем спринте поработаем хорошо. Очевидно, что такая ретроспектива не принесла никакой пользы. Так что команду нужно обучать.
  • Выявлять истинные причины, которые привели к неудаче в спринте. Использовать, например, метод «пяти почему». Он представляет собой процесс последовательных ответов на пять вопросов «почему», позволяющий выяснить корневую причину проблемы. Каждый ответ на вопрос служит основой для следующего вопроса.
  • Вырабатывать мероприятия, из которых понятно, кто и что должен сделать. Мероприятия должны быть выполнимыми, их нужно включать в качестве задач в следующий спринт.
  • Точно так же надо выявлять и истинные причины успеха — положительные факторы. У людей должно появиться чёткое осознание: какие именно действия помогли одержать победу. И успех не должен ассоциироваться с фокусом, который неизвестно как повторить.
  • Вырабатывать мероприятия, которые закрепят действия команды, приводящие к успеху, и усилят их.
  • Находить проблемы для исследования, даже если видимых сложностей и нет. Например, «мы реализуем задачи в срок, а давайте теперь и ошибки исправлять в срок» или «сведём число ошибок к нулю».
Очень хорошим примером для формирования навыков выявления истинных причин служит разбор причин ошибок. Обычно на вопрос, почему была допущена ошибка, отвечают: плохо тестировали. Однако ошибку в код вносит разработчик, а не тестировщик. Поэтому не так важно, насколько хорошо или плохо тестировали продукт — это не является причиной ошибки. Программист должен выяснить, что заставило его написать ошибочный код. И что он должен был делать или знать, чтобы сразу написать его правильно.
Понятно, что выявлением причин и планированием мероприятий дело не заканчивается. Все эти мероприятия надо не только выполнить, но и убедиться, что они дали положительный эффект.
План качественно проведённой ретроспективы может выглядеть примерно так:
  • проверить выполнение и результат мероприятий по улучшению работы команды спринта;
  • проанализировать достижение целей спринта;
  • проанализировать результат спринта;
  • похвалить команду за высокие показатели и продумать, как улучшить низкие или упавшие;
  • выявить факторы, замедлившие спринт;
  • проанализировать причины программных ошибок, как минимум, наиболее критичных;
  • проанализировать опыт других команд и «примерить его на себя»;
  • выбрать 3−5 показателей, на которых нужно сфокусироваться в ближайшем спринте;
  • зафиксировать мероприятия в результатах ретроспективы и включить в общий бэклог;
  • включить часть мероприятий в бэклог следующего спринта.

РЕТРОСПЕКТИВА

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

Оценка результата

Оценка результата — отправная точка для улучшения командной работы. Система оценки результата работы команды должна мотивировать людей осваивать практики, подтвердившие свою успешность, и придумывать новые, способные повысить эффективность. Нужно понимать, что на освоение процессов и практик может потребоваться по времени от нескольких спринтов до нескольких кварталов. Не бывает так, что сегодня определили подробные критерии готовности задачи к выпуску — и все без исключения команды уже в следующем спринте реализуют все задачи в соответствии с ними, поскольку это итерационный процесс последовательного приближения к цели. Бинарная оценка: соответствует ли задача критериям готовности или нет — не помогает приблизиться к цели. Поэтому оценка результата должна фокусировать внимание команды на её слабых сторонах, но при этом не демотивировать.
В компании «Диасофт» применяется 1000-балльная система. Оценка в 700 баллов говорит, что задача выполнена в пределах нормы. От 0 до 700 баллов — ниже нормы, от 700 до 1000 — соответственно выше. Если критерии готовности задачи к выпуску выполняются, это оценивается в 700 баллов. Если нет, оценка сваливается в диапазон от 0 до 700 баллов, в зависимости от степени готовности. Когда критерии готовности существенно превышены, работа оценивается в интервале от 700 до 1000 баллов. Допустим, текущая оценка выполнения критериев — 100 баллов. Команда включает в спринт мероприятия, улучшающие её деятельность, и ставит себе цель на спринт: достигнуть, например, 200 баллов или, во всяком случае, прироста оценки не менее чем на 10% от текущего результата. Это означает, что если команда достигнет 110 баллов или ниже, то цель по улучшению она не выполнила, а если достигнет 200 баллов, то цель по улучшению выполнена на 700 баллов. Таким образом, оценка мотивирует команду последовательно улучшать свои показатели.
Важно оценивать как можно чаще — тогда появляется возможность быстрее достигнуть целевого результата, поэтому нужно оценивать каждый спринт. Scrum допускает спринты до 4 недель, но я советую ограничить их одной-двумя неделями. При двухнедельных спринтах команда получает до шести оценок за квартал, следовательно, шесть возможностей корректировки своей деятельности.
Чтобы оценивать команды, нужно:
  • определить показатели для оценки результата работы команды в спринте;
  • разработать правила расчёта показателей;
  • определить, в каких разрезах делать расчёт показателей, например:
  • по организационной структуре:
  • производственный центр;
  • руководитель продукта;
  • команда.
  • по периоду расчёта:
  • спринт;
  • последние 30 дней;
  • квартал;
  • год;
  • реализовать отчёты по расчёту показателей по правилам;
  • запустить процедуру ежедневного расчёта показателей.
Как видите, выглядит просто. И для идеального мира этого было бы достаточно. Но мы живём в мире реальном. Ожидая оценок, команды хотят быть хорошими. Или хотя бы такими выглядеть. И тогда на помощь приходят нечестные методы, стремление «срезать углы». В английском языке это называется fraud, а по-русски имеет вполне определённое значение — мошенничество.
Вот вроде все мы знаем правила дорожного движения, тем не менее, множество водителей их нарушает. Почему? Одна из причин выглядит вполне анекдотично: «все так делают, и я тоже». Новички, попадая в такую среду, могут даже не догадываться, что они нарушают правила. Можно ли бороться с причинами, досконально разбираясь в каждой и обсуждая её с каждым нарушителем? Наверное, можно, но очень сложно, дорого и, скорее всего, без видимого результата. Существенно снизить нарушения правил движения смогли только повсеместно установленные камеры видеофиксации.
Когда количество команд в компании исчисляется десятками, а то и сотнями, без тотального контроля над исполнением правил не обойтись. Но не забывайте о презумпции невиновности. Команды не должны ощущать контроль, особенно те, кто всё делает по правилам. А с нарушителями нужно часто и откровенно говорить — для профилактики, и помогать им честно зарабатывать высокие оценки. Что делать, если нарушителем стала ведущая команда с хорошим послужным списком? С такой командой нужно говорить в первую очередь и переводить её из ряда нарушителей в ряд образцово-показательных. Я пользуюсь следующим примером: «Понимаю, что ваша команда результативна, и нарушения, по существу, не влияют на результат, поскольку у вас накоплен большой опыт. Но вы же — одна из ведущих команд. На вас, как на образец, смотрят другие и пытаются копировать. Не понимая сути ваших мелких хитростей, они вслед за вами нарушают правила и портят конечный результат. Вы же не станете перебегать оживлённую дорогу в неположенном месте или на красный свет, если рядом дети, ваши или чужие, без разницы? Потому что понимаете, что, следуя вашим действиям, они могут просто погибнуть под колёсами. Так что соблюдайте правила и показывайте хороший пример молодым или менее опытным».
Практический пример показателей для оценки результата спринта:
  • держи слово — количество сделанных задач, взятых в спринт;
  • делай больше — количество сделанных задач сверх нормы;
  • делай быстро — количество задач, решённых в рамках нормативов или дешевле;
  • делай красиво — соответствие кода критериям качества.
ДЕРЖИ СЛОВО
Держи слово — количество сделанных задач, взятых в спринт.
Этот показатель призывает команду выполнять все принятые в рамках спринта обязательства. Фактически, планируя спринт, она даёт слово заказчику сделать все взятые задачи. Показатель учит тому, как правильно воспринимать планирование спринта. Поскольку в проектах допускается изменение первоначального плана, переходя на работу в спринтах, люди психологически склонны к подобному отношению, следовательно, воспринимают планирование не слишком серьёзно — да и правда, зачем сильно в него вкладываться, если план потом поменяется?
Показатель «держи слово» заставляет относиться к плану как к тому, что нельзя изменить. Дал слово — держи. Хорошо или плохо, когда команда выполнила 9 задач из 10? Это означает, что команда не сдержала слово, а значит — плохо. Хорошо — это выполнить десять из десяти взятых в спринт задач.
По сути, «держи слово» — это отношение количества сделанных задач ко всем взятым в спринт. Сделанными считаются те, что соответствуют критериям готовности к выпуску. А какие задачи считаются взятыми в спринт? Казалось бы, ответ простой: задачи, взятые в бэклог спринта при его планировании. Однако это не просто технически проверить. На обзоре результата вам сдают десять задач. Точно ли вы знаете или помните, что именно они были взяты в бэклог? Возможно, вам показывают только то, что смогли или захотели сделать? Заказчик вполне мог что-то забыть за две и, тем более, за четыре недели. А если он работает с несколькими командами? Или (случается и такое) вступает в сговор с командой, по причине своей управленческой слабости или просто не желая портить отношения?
Поэтому должно быть определено правило: как фиксируется результат планирования спринта. Скажем, бэклог спринта — это задачи, включённые в план в первый, а не в последний день спринта. Другими словами, в первый день команда должна зафиксировать бэклог, причём нормированная трудоёмкость включенных в спринт задач должна соответствовать фокус-фактору 0,7. Поэтому если команда в первый день фиксирует задачи, отвечающие фокус-фактору 0,5, а через два дня доберёт до фокус-фактора 0,7, показатель «держи слово» примет во внимание лишь задачи, поставленные в первый день. А раз полный объём спринта не зафиксирован, то и максимальный балл показателя снижен. В нашем примере вместо 700 — всего 500 баллов.

КАК МЫ ОЦЕНИВАЕМ КОМАНДЫ

Бинарная оценка: соответствует ли задача критериям готовности или нет — не помогает приблизиться к цели. Поэтому оценка результата должна фокусировать внимание команды на её слабых сторонах, но при этом не демотивировать.
ДЕЛАЙ БОЛЬШЕ
Делай больше — количество сделанных задач сверх нормы.
Показатель «делай больше» поощряет способность команды сделать в спринте больше задач, чем взято изначально. А так бывает при определённых условиях.
  • У команды нет ошибок, значит, она может больше времени потратить на новые задачи.
  • Бэклог спринта полностью сформирован, а заказчикам в те же сроки нужны ещё задачи. Команда может взять их, фактически соглашаясь на переработку. Злоупотреблять этим нельзя.
  • Команда нашла эффективный способ решения взятых задач и высвободила себе время на дополнительные задачи.
Команды нужно мотивировать к тому, чтобы они брали на себя больше задач. Есть множество причин, почему у команды появляется свободное время. Главное, чтобы вместо простоя она потратила его на что-то полезное. А для этого, во-первых, у людей должны быть дополнительные задачи, готовые к реализации, а во-вторых — правильная мотивация.
ДЕЛАЙ БЫСТРО
Делай быстро — количество задач, решённых в рамках нормативов или дешевле.
Показатель «делай быстро» определяет эффективность работы команды в спринте. Каждая задача, взятая в него, имеет нормативную трудоёмкость, и её надо выполнить, не превышая этой трудоёмкости. Почему это важно? Команда может справляться со всеми задачами, взятыми в спринт, то есть — держать слово. Но какой ценой это достигается? В сутках 24 часа, в рабочем дне всего лишь восемь, и людям приходится постоянно перерабатывать. Долго в таком режиме команда работать не сможет: упадёт производительность, или люди, устав, уволятся. Поэтому команда должна научиться попадать в нормативы, в том числе и для того, чтобы всё успевать и не перерабатывать. К сожалению, и здесь возможен фрод, когда сотрудники списывают не фактически потраченное, а ожидаемое количество часов.
ДЕЛАЙ КРАСИВО
Делай красиво — соответствие кода критериям качества.
Показатель «делай красиво» мотивирует соблюдать стандарты качества кода, вовремя исправлять критические ошибки, снижать количество выявляемых инспектором кода ошибок, сокращать технический долг. И, в частности, прибегает к «правилу бойскаута» из кодекса разработчика: «оставляй лагерь после себя чище, чем было до твоего прихода». Применительно к нашей работе это означает, что после доработки исходного кода количество выявляемых инспекторами кода ошибок должно быть нулевым или, по крайней мере, меньше, чем до доработки. То есть если программист берёт код микросервиса, где инспектор кода выявил десять ошибок, то после доработки таковых не должно остаться больше девяти. Это мотивирует программиста заниматься своим кодом и улучшать его.

НОРМАТИВЫ

Метод оценки работ по разработке программных продуктов, о котором я расскажу в этом разделе, может показаться вам необычным. Во всяком случае, я не встречал подобного подхода к оценке ни в одной книге, статье или компании. Тем не менее, он широко используется в других отраслях и, как показывает практика, прекрасно работает в производстве программных продуктов. Вот уже несколько лет сто команд компании «Диасофт» успешно его применяют.
Эффективность метода не зависит от архитектуры разрабатываемого продукта или языка программирования. Мы успешно применяем его при разработке программных продуктов в двухуровневой, трёхуровневой и микросервисной архитектурах, а кроме того, при разработке мобильных приложений, системных компонентов и продуктов для обработки больших данных.
Ремарка: в этом разделе, чтобы упростить изложение основной идеи, под термином «разработчик» понимается команда, решающая задачу. Она может включать аналитика, программиста, тестировщика, технического писателя и другие необходимые роли.

Проблемы оценки задач

Типовой процесс оценки трудоёмкости выглядит следующим образом: на вход разработчику приходит набор требований или краткая концепция реализации, отвечающая на вопрос: что надо сделать. Разработчик на основе своего опыта решения аналогичных задач или другим похожим способом оценивает, за сколько часов или дней он её решит. Это одна из причин, почему порой разработчики дают разную оценку одной и той же задаче, а оценки существенно отличаются друг от друга. При этом разработчик закладывает в оценку и собственные риски, по статистике, как правило, удваивает оценку. Менеджер проекта также закладывает свои риски, в зависимости от методики от 20 до 100%. В итоге конечная стоимость задачи может в четыре раза отличаться от реальной.
Но, к сожалению, даже такая перестраховка не гарантирует, что задачу сделают согласно сделанной оценке. Здесь сказывается несколько факторов: во-первых, завышенная оценка расслабляет разработчика, и он решает задачу медленнее, чем мог бы. Включает незапланированные работы, например, рефакторинг кода, дополнительные функции по своему разумению. Во-вторых, он поверхностно анализирует задачу при оценке и, лишь «погрузившись в код», понимает глубину кроличьей норы. В итоге, потратив половину или больше времени непонятно на что, разработчик понимает, что не успевает, и включается в реальные работы по задаче и, в итоге, само собой, не укладывается в оценку. В следующий раз он включит очередной риск в свою оценку и т. д. Проект попадёт в «порочный круг» постоянного увеличения итоговой оценки работ. Этот эффект можно сравнить с механизмом, который разбалтывается в процессе работы и, в конечном счете, выходит из строя.
Как разорвать этот «порочный круг»? Идея в том, чтобы не запрашивать оценку у разработчика, а разложить задачу на типовые работы, причём каждая из них должна иметь установленную нормативную трудоёмкость

НОРМАТИВЫ

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

Оценка задач через типовые работы

Проще всего понять идею оценки задач через типовые работы можно на примерах из обычной жизни. Мы постоянно пользуемся этим подходом, сами того не осознавая. Но почему-то при оценке задач по разработке программных продуктов выбираем иные пути. Для полноты картины приведу два примера, один взгляд — со стороны исполнителя, а другой — со стороны заказчика.
ВЗГЛЯД СО СТОРОНЫ ИСПОЛНИТЕЛЯ
Как странно выглядела бы наша жизнь, если бы мы готовили ужин так же, как разрабатываем программный продукт. Начнём с простого примера по приготовлению гречки. Скорее всего, каждый из нас хотя бы раз в жизни готовил гречневую кашу или хотя бы видел, как это делают. Кажется, что может быть проще: вскипятил воду и засыпал в кастрюльку крупу. Вряд ли вы задумывались о том, сколько времени уходит на эту процедуру и через какое время каша будет готова. Если спросить хозяек, одна ответит, что ей хватает получаса, другая назовёт 20−25 минут, а кто-то укладывается и в пятнадцать. Напоминаем, процесс предельно простой, а результаты опроса так разнятся между собой. Разный опыт, разные подходы…
Аналогичную картину обнаружим и в разработке программных продуктов. Кто-то простую работу делает за одно время, а другие — в разы дольше. Потому что они не знают, что её можно сделать быстрее. Опыт компании «Диасофт» подтверждает, что одно лишь информирование о том, за какой срок может выполнить задачу ведущий разработчик, повышает общую производительность вдвое.
Вернёмся к нашему ужину. Казалось бы, какая разница, сколько минут варится гречка? Подумаешь, на 15 минут дольше (тем более, что варится каша сама собой, и следить за ней не нужно). А если вы варите её каждое утро на завтрак, когда любая минута на счету? Приготовление гречневой каши — хороший пример типовой работы. Результат приготовления имеет ценность для заказчика — кашу сразу же можно есть. Но вряд ли имеет смысл разбивать задачу на отдельные составляющие: например, залить воду, вскипятить, посолить, засыпать крупу, снять пенку, проверить готовность. Сами по себе эти составляющие не имеют никакой ценности для заказчика. Какие-то шаги можно и пропустить: кто-то ест всё без соли, а кто-то просто заваривает крупу кипятком и даёт ей слегка настояться. Качество и полезность каши от этого не пострадают. И если ты хоть раз успешно сварил гречку, нет нужды лезть в интернет в поисках рецепта. Точно так же и в разработке — нет смысла каждый раз готовить для программиста техническую документацию о том, как программировать визуальную форму.
Усложним бытовую задачу. Предположим, вам нужно приготовить ужин из нескольких блюд на пять-шесть гостей. Сначала вы продумываете меню: из каких блюд будет состоять ужин. Например, мясная и сырная нарезка, овощной салат и, допустим, на горячее — мясо. Фактически, вы разложили задачу на типовые работы, каждая из которых имеет самостоятельную ценность. Вы знаете, как приготовить каждое блюдо, так как делали это уже неоднократно. Рецепт требуется лишь для мяса, которое вы решили приготовить по-новому.
А что в разработке программного продукта? Да то же самое: сначала задачу нужно разложить на типовые работы, и только по тем работам, которые команда ещё не выполняла или по которым должна реализовать новый алгоритм, требуется подробное техническое задание.
Если вы готовитесь к ужину, то непременно проинспектируете холодильник, чтобы убедиться, что в нём есть необходимые продукты, а чего нет — надо докупить. Однако программист не пытается заранее понять, всего ли ему хватает, чтобы выполнить задачу. Его стандартный ответ таков: «Когда приступлю к задаче, открою код и пойму, что надо делать». В переводе на язык приготовления звучит так: «Когда приступлю к готовке, открою холодильник и пойму, какие продукты есть, а каких нет. И буду ходить в магазин за каждым отдельно». Ясно, что при таком подходе с ужином у вас будут проблемы.
Продолжим аналогию. Вам нужно оценить, сколько времени понадобится на приготовление ужина согласно придуманному меню. И вы не оцениваете его, основываясь на предыдущем опыте. Например, в прошлый раз я готовил три часа и не успел. Люди пришли, а мясо ещё полчаса было в духовке. Значит, сейчас начну готовить за четыре часа до прихода гостей, чтобы уж точно успеть. А при разработке программного продукта оцениваем именно так, исходя из предыдущего опыта, а не реального набора работ.
ВЗГЛЯД СО СТОРОНЫ ЗАКАЗЧИКА
Здесь я приведу другой пример, из области строительных работ. Допустим, я хочу отремонтировать квартиру. Как мне, заказчику, оценить стоимость ремонта и понять, что названная исполнителем сумма адекватна, если я не сильно разбираюсь в этой сфере? Взять за основу стоимость ремонта у друзей сложно, поскольку квартиры не похожи друг на друга: разная площадь, количество комнат, дизайн, материалы. Да и ремонт мне будут делать совсем другие люди.
Согласитесь, что это типичная ситуация для заказчика разработки программного продукта. Он не разбирается глубоко в хитросплетениях процесса разработки и не в силах оценить адекватность полученной оценки. Разложение задачи на понятные, имеющие ценность для заказчика, типовые работы существенно упрощает понимание оценки.
Тот же ремонт квартиры легко раскладывается на типовые работы: стяжка, настил пола, поклейка обоев, установка десяти электрических розеток и так далее. Результат каждой из этих работ имеет ценность для заказчика. На установку одной розетки уходит 30 минут, значит, на десять штук потребуется пять часов. Следовательно, если бригада станет заверять, будто на эту работу ей нужно не меньше двух дней, я, заказчик, легко пойму: либо меня обманывают, завышая трудоёмкость, либо я нанял неопытных людей. С другой стороны, если оплата пяти часов на установку розеток окажется для меня слишком дорогой, я могу поменять задачу, ограничившись, к примеру, четырьмя розетками вместо десятка.
Если перевести аналогию на разработку, то и здесь надо прежде всего определить перечень типовых работ, на которые можно разложить любую задачу заказчика: скажем, экранная форма, отчётная форма. Важно, чтобы результатом типовой работы стал артефакт, имеющий ценность для заказчика, у которого должна быть возможность лично увидеть и оценить результат. Каждой типовой работе назначается нормативная трудоёмкость, то есть время, за которое она должна быть выполнена. Кстати, её лучше установить, взяв за основу высококвалифицированного разработчика, даже если далеко не все в вашей компании смогут сразу уложиться в данный норматив. Сделав замер: сколько на самом деле ваши разработчики тратят времени на одинаковую работу — вы удивитесь разбросу значений. Напомню вам пример с марафоном, где норматив соответствует уровню мастера спорта, к которому бегуны стремятся приблизиться путём тренировки. К нашему случаю он вполне подходит: необходимо обучать и тренировать команды делать типовую работу согласно нормативной трудоёмкости. Тогда все они, в конце концов, смогут выполнять её согласно нормативам, существенно повысив свою эффективность.
Процесс оценки проекта с нормативами выглядит следующим образом. На вход разработчику приходит задача с набором требований. Разработчик декомпозирует задачу на типовые работы. Калькулятор по нормативам типовых работ автоматически вычисляет плановую трудоёмкость задачи. Заказчик по списку типовых работ понимает, что именно будет сделано, сколько это стоит, и может при необходимости осознанно изменить этот список. Таким образом, оценка для заказчика становится прозрачной. Он понимает, за что платит свои деньги.

Несколько дополнительных штрихов к нормированию работ

Необходимо давать норматив на выполнение работы целиком. Тогда заказчик будет знать полную стоимость работ. Под полной стоимостью понимается совокупность всех работ всех членов команды по реализации требуемого заказчику артефакта, а также отсутствию скрытых (чаще технических) незапланированных работ. Другими словами, если нормативная трудоёмкость создания формы пользовательского интерфейса один восьмичасовой день, в неё уже включены работы аналитика, дизайнера, программиста, тестировщика, технического писателя и других необходимых ролей. Команда самостоятельно решает, кто сколько может потратить на задачу — с тем, чтобы она была решена в рамках нормативной трудоёмкости. Этот способ помогает команде понять, какие работы приводят к результату, а какие — лишние. К слову сказать, «лишние» и при этом необходимые, с точки зрения принятых в компании стандартов и процессов, работы — первые кандидаты на автоматизацию.
Приведу пример скрытых работ. Команда реализовала алгоритм согласно нормативу, но выпустить его не может, поскольку нужно ещё сохранить результаты работы алгоритма в базе данных. Таким образом, пока они не сохранены, задача не имеет ценности для клиента.
Типичной ошибкой при определении типовых работ становится выделение технических работ, например, «разработка кода» или «тестирование», вместо тех, результатом которых заказчик уже может воспользоваться. В примере с ремонтом квартиры, мне, заказавшему поклейку обоев, совершенно не важно знать технические подробности о том, как нарезаются их куски или наносится клей. Эти работы (безусловно, важные для исполнителя) не несут для меня отдельной ценности.
Типовые работы, например, те же экранные формы, могут быть разной сложности. Очевидно, что трудоёмкость реализации формы с 10 полями ниже, чем с сотней полей. Хотя трудоёмкость форм с 5 и 10 полями различается несущественно. Поэтому, чтобы не усложнять оценку, каждую типовую работу советую разбить на три уровня сложности: простой, средний и сложный. Если трудоёмкость «простого» уровня принять за единицу, к среднему она возрастает вдвое, а к сложному — вчетверо, то есть до четырёх. Такой подход немного снижает точность оценки, но сильно её упрощает. Чтобы команды осознанно выбирали уровень сложности, нужны критерии, по которым он выбирается. Например, экранные формы с количеством полей до 10 — простая форма, до 50 — средняя, свыше 50 — сложная. Критерии нужно выбирать так, чтобы примерно 50−60% всех задач попадали в критерии простой формы, 30−40% - средней формы и не более 10% оставалось на сложные.

Польза нормативов

Внедрение нормативов в работу команд решает несколько концептуальных проблем разработки программных продуктов:
  • существенно упрощается оценка и повышается её точность;
  • оценка становится прозрачной для заказчика;
  • оценка не зависит от человеческого фактора;
  • команды выполняют одинаковые работы за одно и то же нормативное время;
  • применение нормативов снижает стоимость разработки программных продуктов в 10−12 раз;
  • только ввод нормирования сразу поднимает эффективность вдвое. Ведь кто-то делает простую работу быстрее, а кто-то — медленно. Публичная производственная среда подталкивает людей тянуться за лучшими, и производительность в среднем растёт;
  • далее идёт работа над тем, чтобы нормативы уменьшались. Здесь потенциал — до трёх раз. Как? Например, DevOps (убираем ручной труд там, где возможно), рост компетенций сотрудников и мотивации (публичная соревновательная среда);
  • ликвидация ручного труда поднимает качество кода. Это позволяет выделять больше времени в спринте на создание нового кода, а не на исправление ошибок. Здесь — ещё удвоение эффективности. В компании «Диасофт» фокус-фактор увеличен с 35 до 70%, за два года, по сути, в два раза.
Фактически набор типовых работ становится языком (или своего рода словарём) между заказчиком и исполнителем. Наличие общего языка упрощает их взаимодействие и взаимопонимание, повышая удовлетворённость заказчика.

DevOps

DevOps (англ. development и operations) — методология активного взаимодействия специалистов по разработке и информационно-технологическому обслуживанию, а также взаимная интеграция их рабочих процессов для обеспечения качества продукта. DevOps предназначен для эффективной организации создания и обновления программных продуктов и имеет в основе идею тесной взаимозависимости их создания и эксплуатации, которая прививается команде так же, как культура разработки.
Зачем нужен DevOps? Между разработчиками и поддержкой существует барьер. Цель разработки — как можно быстрее реализовать бизнес-требования и добавить их в работающий продукт. Поддержка отвечает за то, чтобы приложение работало стабильно, а любые изменения ставят стабильность под угрозу. Когда приложение не работает, разработчики и поддержка принимаются обмениваться фразами «проблема на вашей стороне». В итоге страдают пользователи — а им всё равно, какая часть команды несёт ответственность за поломку. Налицо конфликт интересов. DevOps появился, чтобы его разрешить.
Укрупнённо можно назвать следующие задачи DevOps.
  • Сократить время доставки изменений до клиента (англ. time to market). Измеряется от даты первого внесения изменения в код до установки на рабочий стенд. Отличным считается срок одна неделя. Плохим — три месяца.
  • Убрать барьеры между командами разработки, администрирования и поддержки. Задача, в частности, включает планирование развёртывания сред до начала кодирования и ускоряет получение обратной связи от клиента до разработки.
  • Создать культуру взаимодействия в команде, когда ответственность за правильно работающий на рабочем стенде продукт лежит на каждом её участнике.
  • Создать культуру постоянного экспериментирования, которая требует принятия рисков и извлечение уроков из успехов и неудач, а также понимание того, что повторения и практики являются предпосылкой к мастерству.
Фактически DevOps — это совокупность практик, процессов, инструментов и культуры взаимодействия для непрерывной доставки ценностей заказчикам. DevOps базируется на методологии разработки CI/CD (англ. continuous integration/continuous delivery, в переводе — «непрерывная интеграция» или «непрерывное развёртывание»).
Основные практики DevOps:
  • непрерывное тестирование;
  • непрерывная интеграция;
  • непрерывная доставка;
  • непрерывное развёртывание;
  • непрерывный мониторинг;
  • инфраструктура как код;
  • построение CI/CD-конвейера.

Культура взаимодействия

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

DEVOPS

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

Непрерывное тестирование

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

Непрерывная интеграция

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

Непрерывная доставка и развёртывание

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

Инфраструктура как код

«Инфраструктура как код» — модель, по которой процесс настройки инфраструктуры аналогичен процессу программирования. По сути, это устранение границ между написанием приложений и созданием сред для них. Приложения могут содержать скрипты, которые создают собственные виртуальные машины и управляют ими.
Инфраструктура как код позволяет управлять виртуальными машинами на программном уровне. Это исключает необходимость ручной настройки и обновлений для отдельных компонентов оборудования. Инфраструктура становится чрезвычайно «эластичной», то есть воспроизводимой и масштабируемой. Один DevOps-инженер может выполнять развёртывание и управление как одной, так и тысячей машин, используя один и тот же набор скриптов.
Модель позволяет заметно, с нескольких недель до нескольких минут, сократить время и затраты на развёртывание и настройку гарантированно рабочего стенда. Создание новых стендов или обновление существующих выполняется в полностью автоматическом режиме.
Кроме того, эта модель позволяет решить частую проблему, известную как «дрейф конфигурации». Нередко администраторы системы и приложений вносят ручные настройки в тестовые среды для оптимизации производительности или кастомизации решения под задачи конечного пользователя. Эти изменения нужно тиражировать на другие среды, включая рабочую. Ручные настройки могут быть забыты, особенно в условиях, когда за тестовую среду отвечают одни администраторы, а за рабочую — другие. В итоге накапливаются расхождения в настройках разных сред, что приводит к сложным в отладке сбоям. Современные средства конфигурационного управления, такие как Ansible, позволяют автоматизировать соответствующие задачи и обеспечивать их оркестровку на всех стендах с помощью скриптов.

Непрерывный мониторинг

Непрерывный мониторинг — практика постоянного сбора метрик о состоянии приложения на каждом шаге в процессе доставки программного продукта, включая его состояние на рабочем стенде. Чем раньше информация об аномалиях работы приложения будет доступна команде, тем лучше — она сможет исправить ошибку или поднять производительность раньше, нежели пользователь сможет это заметить.
При развёртывании программного продукта на рабочем или тестовом стенде к нему подключаются системы мониторинга, например, Digital Q.Health или Prometheus. Они контролируют, как работает продукт, записывают все ошибки и отклонения от нормальной работы в специализированные журналы, оповещают команды разработки об ошибках и других проблемах, автоматически выполняют восстанавливающие работу скрипты, например, перезагружают сбойный микросервис, и отключают пользователям доступ к сбойным функциям. Стандартной считается практика использования метрик мониторинга для автоматического масштабирования микросервисов при увеличении нагрузки и автоматического высвобождения ресурсов при снижении. Это позволяет бережно относиться к имеющимся ресурсам.
Важно, что в DevOps этапы разработки идут параллельно, а не друг за другом. Пока программисты работают над одним кодом, другую его часть уже тестируют, а ещё одну мониторят. И в это же время все члены команды анализируют результаты мониторинга, могут видеть аномалии работы всей системы, а не только разрабатываемой функции, и формируют новые задачи на разработку.

Как получить пользу от внедрения DevOps?

Внедрение культуры и практик DevOps позволяет получить заметные преимущества.
  • Существенное сокращение сроков доставки новых продуктов до конечных пользователей. С шести и более месяцев — до одной недели.
  • Существенное сокращение времени между обнаружением ошибки на рабочем стенде и её исправлением. С нескольких дней и недель — до часов.
  • Существенное снижение затрат на изменение кода программного продукта, находящегося в промышленной эксплуатации. Затраты на этапе эксплуатации не отличаются от затрат на этапе разработки (хотя прогнозировалось, что цена изменений с каждой стадией разработки будет увеличиваться на порядок). При непрерывном развёртывании все стадии разработки происходят за один день, осуществляются одной и той же командой разработки, поэтому экспоненциального увеличения затрат нет.
  • Стоимость выпуска релиза и пакетов исправлений стремится к нулю, за счёт полной автоматизации процесса выпуска. Это позволяет проводить процедуру выпуска столько раз в день, сколько требуется, например, после каждого внесения изменения кода в кодовую базу. При этом роста затрат, связанных с выпуском, нет.
  • Унификация процесса выпуска и используемых тестовых сред. В традиционном подходе к разработке программного продукта у каждого программиста — своя тестовая среда и свой набор шагов тестирования, что часто приводит к тому, что локально отлаженный программистом код не работает на тестовом стенде.
  • Широкие возможности для экспериментов. Традиционно вариант реализации функционала выбирают после тщательной предварительной оценки: выбранные функции умозрительно проектируются, затем реализуются и сдаются в эксплуатацию. В условиях непрерывного развёртывания нужно относиться к каждой планируемой функции как к эксперименту, и некоторые уже выпущенные функции впоследствии отомрут. Так, при проектировании пользовательского интерфейса разработчики ориентируются на собственное понимание удобного интерфейса. Что для конечного пользователя совсем не очевидно. Современный подход даёт пользователю возможность самому решить, что для него удобно, а что нет. Для этого выпускают несколько версий пользовательского интерфейса, разным группам предоставляют доступ к разным вариантам. Вариант, набравший большее количество положительных отзывов, остаётся в продукте, остальные отключают.
Кажущаяся простота концепции DevOps и его очевидная польза легко вводят в заблуждение: оно может внедриться само. Это не так.
Ниже перечислены шаги, которые необходимо выполнить для успешного внедрения DevOps.
  • Разработка CI/CD-конвейера для каждого типа разрабатываемого программного продукта. Например, один — для микросервисов на Java, другой — для них же на Python.
  • Разработка количественных показателей, определяющих, насколько широкое распространение получили практики DevOps.
  • Во-первых, показатели должны измерять, насколько полно отработан каждый шаг CI/CD-конвейера. Например, процент покрытия кода проходящего по конвейеру продукта, автоматическими тестами. Недостаточно лишь факта о наличии автоматических тестов. Если их мало, доверять результату такого тестирования нельзя.
  • Во-вторых, показатели должны измерять глубину внедрения, то есть какие шаги CI/CD-конвейера уже выполняются, какие увеличивают покрытие кода, а какие ещё только планируются к внедрению. По каждому микросервису значения показателей будут различаться.
  • В-третьих, показатели должны измерять охват CI/CD-конвейером разрабатываемых продуктов. Стопроцентным охватом считается, если по любому изменению кода каждого разрабатываемого продукта запускается CI/CD-конвейер.
  • Разработка количественных показателей, которые будут определять реальную пользу от внедрения DevOps. В частности, важно измерять время доставки новых продуктов и функций до конечного пользователя.
  • Подключение гарантированного запуска CI/CD-конвейера при любом внесении изменения в кодовую базу для каждого типа разрабатываемого продукта. Лучше это делать с помощью средств системы управления версиями кода, чтобы независимо от способа внесения изменений гарантированно запускался CI/CD-конвейер.
  • Постоянное измерение глубины и охвата внедрения DevOps. Актуальная информация о широте его распространения позволит сделать вывод, где уже есть польза, а где — только планируется.

ИНФРАСТРУКТУРА

Современное производство программного обеспечения предъявляет весьма жёсткие требования к поддерживающей его инфраструктуре. Например, каждая команда создаёт компоненты полностью самостоятельно, следовательно, ей необходимы свои стенды для разработки, тестирования и выпуска. Изоляция стендов нужна, поскольку ошибки в работе функционала одной из команд на едином стенде могут остановить работу других. В итоге на крупных производствах количество стендов начинает измеряться сотнями и тысячами. Очевидно, что для управления ими необходима автоматизация. Также понятно, что держать все стенды в рабочем состоянии, даже когда они в данный момент не нужны команде, оборачивается, как минимум, неэффективным использованием оборудования. Поэтому в современном производстве программных продуктов возникла и успешно реализуется идея создания «стенда по требованию». Стенд создаётся по одной кнопке, ровно тогда, когда нужен, и удаляется, как только в нём отпадает необходимость. Здесь используется подход PaaS.

PaaS

Платформа как сервис (PaaS) — способ предоставления клиенту готовой к использованию программной среды. Ошибочно считается, будто данный подход применим только к облачным вычислениям. Ничего подобного, он отлично работает локально, при использовании собственной инфраструктуры. PaaS предоставляет инфраструктуру и программное обеспечение среднего слоя (СУБД, платформы управления контейнерами, брокеры сообщений, серверы приложений), что даёт возможность разработчикам, администраторам и конечным пользователям создавать, интегрировать, переносить и развёртывать программные приложения.
До появления PaaS разработчикам, прежде чем создавать приложение, приходилось закупать или запрашивать из имеющегося пула физические или виртуальные сервера, указывая, сколько нужно выделить технических ресурсов на каждый сервер. Например, сколько нужно процессорных ядер, какой частоты, сколько оперативной памяти, и каков должен быть объём дискового пространства. Если каких-то параметров становится мало, запрашивается расширение или модернизация сервера. Не всегда можно обойтись простым расширением ресурсов. Скажем, невозможно увеличить размер жёсткого диска, так что приходится ставить новый диск большего объёма и производить долгую процедуру миграции на новый диск, а иногда — на новый сервер. Разработчики были обязаны самостоятельно заботиться об установке и администрировании необходимого программного обеспечения среднего слоя, что усложняло производственные процессы. На подготовку к работе одного сервера могло уходить от недели до нескольких, в зависимости от количества необходимых к установке продуктов.
PaaS базируется на подходе IaaS (инфраструктура как сервис), состоящем в предоставлении вычислительной инфраструктуры в краткосрочное пользование или аренду. IaaS предоставляет совокупность виртуальных машин, хранилищ данных, сетевых элементов различных типов. Такая среда практически всегда является гибкой и масштабируемой. Неиспользуемые ресурсы могут высвобождаться в автоматическом режиме, а при дополнительной нагрузке быстро вводятся в строй новые.
PaaS существенно повышает эффективность процессов управления IT:
  • ускоряет выделение необходимых ресурсов и оптимизирует масштабируемость;
  • улучшает автоматизацию и устраняет рутинные, часто выполняемые вручную, задачи;
  • стандартизирует развёртывания, что сокращает количество поставщиков технологий.

PAAS IAAS

Виртуализация и контейнеризация

Виртуализация появилась как средство для уплотнения программных окружений на одном и том же физическом сервере. До виртуализации программный продукт выполнялся на физическом («железном») сервере, причём полностью его ресурсы не использовались. Сейчас, чтобы максимально полно утилизировать производительные мощности и запускать на одном и том же физическом сервере больше программных систем, используют виртуализацию. Речь идёт о полной изоляции ресурсов: в виртуальной машине — полностью изолированное ядро, все библиотеки, строго ограниченные ресурсы по процессору и памяти.
Таким образом, виртуализация — это механизм виртуального представления ресурсов без привязки к аппаратному обеспечению. Виртуализировать можно серверы, СХД, сетевые ресурсы, приложения и рабочие столы.
Контейнеризация — облегчённая форма виртуализации на уровне операционной системы, она позволяет запускать приложение в изолированной области — «контейнере», каждый из которых содержит все компоненты, необходимые для запуска приложения. Он не зависит от архитектуры серверной системы и взаимодействует с операционной системой при помощи стандартных интерфейсов. В этом программные контейнеры похожи на транспортные из реального мира — неважно, что внутри контейнера, главное, чтобы он имел стандартные интерфейсы. Контейнеры — более лёгкие и компактные по сравнению с традиционными виртуальными машинами, они очень быстро запускаются, используют общую операционную систему. Их можно создавать гораздо быстрее, чем экземпляры виртуальных машин. Каждый контейнер — по сути, отдельный сервис, его обновление не требует синхронизации с другими, а инкапсуляция в нём всего необходимого для запуска приложения облегчает перенос из одной среды в другую. Наиболее распространённая технология реализации контейнеров — Docker.
Docker — продукт с открытым исходным кодом для автоматизации развёртывания приложений в виде переносимых автономных контейнеров, выполняемых в облаке или локальной среде. Результатом процедуры выпуска микросервиса становится Docker-образ, размещённый в реестре Docker-образов. Docker-образ — это шаблон, который содержит операционную систему, системные библиотеки и собранное приложение. Образы используются для создания контейнеров. Из одного образа может быть создано и запущено много экземпляров контейнеров. Их можно запустить в операционной системе как отдельный изолированный процесс или в системе управления контейнерами. Самая распространённая платформа управления контейнерами — Kubernetes.
Kubernetes — программный продукт с открытым исходным кодом, предназначен для оркестровки контейнеризированных приложений: автоматизации развёртывания, масштабирования и координации в условиях кластера. Все популярные платформы управления контейнерами построены на Kubernetes, например, Digital Q.Kubernetes от компании «Диасофт» или RedHat OpenShift от компании RedHat.
Какие преимущества даёт контейнеризация?
  • Унификация управления контейниризированными приложениями. Так же, как на транспорте, где контейнеры позволили унифицировать средства доставки, погрузки и разгрузки, в нашей сфере они служат унификации средств развёртывания, масштабирования и координации приложений. Не важно, что находится внутри контейнера: СУБД, обученная нейронная сеть, сервис, реализованный на языке Java или любом другом языке программирования, управление контейнером одинаковое. Не требуется разрабатывать уникальный способ под каждое приложение.
  • По сравнению с другими технологиями контейнеризация даёт более высокий и простой в реализации уровень масштабирования. К примеру, один экземпляр веб-сервиса может быть запущен только один раз на одной ноде кластера серверов приложений (каждая нода — это отдельный виртуальный сервер). Таким образом, число экземпляров веб-сервиса определяется количеством нод кластера серверов приложений или виртуальных серверов. Практика показывает, что управление даже 15–20-нодовым кластером серверов приложений очень сложно и требует больших трудозатрат. И с добавлением каждой следующей ноды сложность быстро растёт. Операции ввода новой или вывода сбойной ноды и конфигурирования практически не могут выполняться в автоматическом режиме. Контейнеры же, в отличие от веб-сервисов, хорошо изолированы, и потому на одной ноде кластера можно запустить сколь угодно много экземпляров контейнера. Ограничение — только по свободным ресурсам. Нормальной считается практика запуска тысяч экземпляров контейнеров в пределах одного кластера. Причём управление и конфигурирование производится в полностью автоматическом режиме. При увеличении нагрузки автоматически запускаются дополнительные экземпляры контейнеров, при снижении — так же автоматически удаляются.
  • Нет ограничений в используемых технологиях. Типичной проблемой при использовании сервера приложений является ограничение технологического стека, работающих на нём приложений. Например, если сервер приложений поддерживает Java 8, на нём невозможно запустить веб-сервис, созданный на Java 11. Требуется одновременная смена версии сервера приложений и всех сервисов. Для контейнеризированных приложений таких ограничений нет. Вполне допустимо, что один сервис будет реализован на Java 8, а другой — на Java 11. Они будут работать одновременно и прозрачно взаимодействовать, не мешая работе друг друга. Более того, одна версия сервиса может быть на Java 8, а новая — уже на Java 11. Переход на новую версию сервиса не потребует менять версию системы управления контейнерами, более того, обе версии могут работать одновременно.
  • Высокая устойчивость работы приложений. Обычно, если случается сбой и остановка работы хотя бы одного веб-сервиса, вся нода сервера приложений выходит из строя. Практика показывает, что сбой одной ноды сервера приложений запускает «эффект домино», приводя к сбою всех остальных нод кластера. Сбой же работы одного и даже нескольких контейнеров не влияет на работу других контейнеров и всей ноды кластера. Сбойный экземпляр автоматически удаляется, и на его место запускается новый экземпляр.
  • Более простой процесс развёртывания и сопровождения приложений.
Имея «под капотом» столь мощные технологии, можно задуматься об автоматическом управлении сотнями и даже тысячами стендов.

Управление стендами

При таком количестве инструментов, продуктов и технологий задача управления сотней или даже тысячей стендов уже не выглядит такой сложной и тем более невыполнимой. Не нужен штат из сотен администраторов — с ней успешно справятся два-три человека.
Учёт всех IT-компонентов (в том числе физических и виртуальных серверов), установленного на них системного программного обеспечения, развёрнутых приложений, а также учёт и планирование целевой конфигурации стендов ведётся с помощью специальной базы данных управления конфигурацией (например, с помощью платформы Digital Q.CMDB).
Развёрнутая платформа управления контейнерами (допустим, Digital Q.Kubernetes) обеспечивает реализацию модели PaaS для команд разработки. При использовании CI/CD-конвейера, реализованного, скажем, в платформе Digital Q.DevOps, и подхода «инфраструктура как код» любое изменение исходного кода в системе версионного контроля кода (например, Digital Q.VCS) порождает сборку Docker-образа с приложением, доставку его до платформы управления контейнерами, затем, при необходимости, автоматическое создание нового стенда по конфигурационной информации из Digital Q.CMDB и развёртывание на нём контейнера. Вся операция выполняется за несколько минут и без участия человека. Информация о новом стенде и его фактической конфигурации автоматически сохраняется в Digital Q.CMDB.
Made on
Tilda