Энтерпрайз разработка с нуля


    На днях у меня появилась довольно интересная идея для статьи, основанная на следующей предпосылке: на Хабре ни разу не рассказывали об организации энтерпрайз разработки "от и до". В плане совсем с нуля и хотя бы до комфортного минимума. За отправную точку я буду брать ситуацию полнейшего хаоса, когда какой-то код существует на машине единственного разработчика, нет системы контроля версий, нет тестовых сред, код объектов БД существует только внутри эталонной продуктивной базы данных, нет никаких процессов сборки и установки, контроля качества кода и так далее. Возможно читатель задастся вопросом "Такое бывает в 2020 году? Разве кто-то еще так разрабатывает?" и будете только отчасти правы. Предлагаю обсудить детали под катом.


    Мне пришло в голову как минимум три возможных сценария:


    • ваша компания отдала всю разработку на аутсорс/аутстафф и регулярно заказывает вендору доработки, а он отдает обратно лишь бинарные дистрибутивы очередной версии системы. И код, и интеллектуальная собственность на ПО вроде бы принадлежит вам, но работать с ним вы абсолютно не умеете. И вот в один прекрасный день вы решаете взять процесс разработки в свои руки. А если контракт в валюте и курс в очередной раз подскочил, то уйти от вендора может захотеться в несколько раз сильнее;
    • вас десантировали в качестве разработчика/руководителя/менеджера в такой проект. На собеседовании обсудили самое важное, сошлись о предполагаемои вознаграждении, проверили ваши скиллы, но как-то умолчали про текущий статус организации процессов. И вот в первый рабочий день наставник предлагает скопировать код проекта из сетевой папки. Уууупс;
    • вы давно работали в таком месте и игнорировали все современные тренды, не читали информационные ресурсы по разработке и вдруг неожиданно прозрели, осознав неэффективность и неактуальность процессов и инструментов. Вам захотелось вести разработку с комфортом, в команде с налаженными процессами и вспомогательным софтом. Это сценарий а-ля современный джаваскрипт для динозавров.

    Примечание: за свои 10+ лет опыта в разработке я сталкивался с каждым из сценариев (на прошлых местах работы).


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


    Начало начал — git


    Итак, предположим вы попали в одну из трех гипотетических ситуаций, перечисленных мной во вступлении. С чего начать? Конечно с git. Это стандарт индустрии, самая распространенная система контроля версий, лучший инструмент организации разработки из базовых и необходмых. Просто установите его на свою машину, зайдите в папку проекта и наберите последовательно эти команды:


    git init
    git add .
    git commit -m "Initial commit"

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


    Работа в команде — GitLab


    Что делать, если в команде более одного разработчика? Все в порядке, git был создан в том числе и для командной работы. И если еще 5-7 лет назад следующим я бы порекомендовал установить и настроить git на сервер, то теперь есть GitLab. GitLab это превосходный пример OpenSource проекта, получившего повсеместное распространение и признание в индустрии.



    Википедия говорит:


    GitLab — веб-инструмент жизненного цикла DevOps с открытым исходным кодом, представляющий систему управления репозиториями кода для git с собственной вики, системой отслеживания ошибок, CI/CD пайплайном и другими функциями.

    Вы можете просто взять дистрибутив GitLab и развернуть его внутри корпоративной приватной сети — получится свой маленький "карманный" GitHub. У GitLab есть платные корпоративные версии, можете изучить список доступных фич здесь. Из приятного — платные фичи постепенно перетекают в бесплатные версии.


    Итак, GitLab может стать краеугольным камнем организации разработки. Он позволяет оперировать понятием "проект". Проект имеет отдельный git-репозиторий, список задач/дефектов (issues), agile-доску, wiki и т.д. Иначе говоря, из коробки и бесплатно вы получаете практически все инструменты, необходимые для эффективной и распределенной разработки. Но обо всем по порядку.


    Хранение кода


    Первое и самое главное — GitLab позволяет эффективно и удобно работать над изменениями в коде. Он полностью поддерживает парадигму Github Flow. Это довольно легковесный процесс, при котором каждое новое изменение реализуется в отдельной ветке, а для слияния с основной кодовой базой существуют т.н. запросы на слияние или merge requests (разг. мерджреквест). Последовательность шагов примерно следующая: из задачи по нажатию одной кнопки создается и новая ветка, и одновременно с ней merge request. Далее разработчик переключается на эту ветку, реализует новый функционал или исправляет ошибку, коммитит изменения локально, пушит на сервер. Вся его работа будет максимально удобно отображена на вкладках запроса на слияние: описание, перечень коммитов, построчный дифф. В момент окончания работы над задачей разработчик снимает флаг "work in progress" (WIP). Для тиммейта это может стать сигналом к проведению кодревью. Отдельные замечания можно заводить прямо из диффа, там же можно предлагать свои изменения, и там же можно их сразу принять. Это очень удобный и эффективный способ проведения кодревью. Можно настроить правило: нельзя слить изменения, пока все дискуссии не будут закрыты. В последних версиях можно так же добавить нужных ревьюверов без назначения задачи.


    Трекинг задач


    Под задачей далее подразумевается некоторая сущность с описанием проблемы/нового функционала/идеи, в рамках которой могут выполняться изменения. GitLab позволяет работать с задачами двумя способами:


    • в виде списка. Это классический способ, в котором задачи управляются в соответствии с их приоритетом;
    • в виде доски. Это настраиваемая agile-доска, в которой можно перетаскивать карточки по зафиксированному в команде процессу.

    Примечательно, что не нужно выбирать, оба варианта доступны одновременно, это всего лишь два способа отображения одних и тех же данных. Можно вешать метки, назначать конкретным людям, оценивать временные затраты, приоритезировать. Но лично для меня самая главная фича GitLab это обсуждения. Приятный интерфейс позволяет вести живую беседу, пинговать коллег и ссылаться на другие сущности с помощью специальных символов (@, #, !, ~ и т.д.), вставлять картинки, файлы, смайлы, графики, математические формулы, mermaid-графы и др. Это весело, интересно, модно-молодежно, что помогает поддерживать здоровые отношения в команде!


    Можно так же завести шаблоны задач (текстовые файлы в репозитории), например типичный шаблон для ошибки мог бы выглядеть так:


    ### Ожидаемое vs Фактическое поведение
    
    ### В какой версии обнаружено
    
    ### Примечения

    Со временем команда наверняка придет к созданию шаблонов, включающих критерии завершения задачи (definion of done, DoD).


    Описание задачи и обсуждения в процессе выполнения могут стать отправной точкой для создания документации по проекту. Рано или поздно появляется необходимость в описания функционала системы. Артефакты работы над задачей в нужный момент помогут вспомнить почему было принято то или иное решение. Причем у этой документации из коробки присутствует связь с кодом, что особенно ценно. Задались вопросом, почему так странно работает? git blame -> номер задачи указан в сообщении коммита -> в описании задачи содержится ответ.


    Прочее


    Так же в GitLab изначально есть замечательная возможность завести wiki проекта. Лично я воспринимаю вики как способ перенести знания из голов сотрудников в текстовую форму. Благодаря тому, что вики встроена в GitLab, можно прозрачно ссылаться на различные сущности вроде коммитов, задач, пользователей, меток и т.д. Это очень удобно. Так же wiki-странички хранят историю изменений. По ощущениям, они являются обычными Markdown-файлами в выделенном git-репозитории. Так же Wiki можно воспринимать как хранилище документации по проекту. О ведении документов вкратце рассказано в последующих главах.


    Майлстоун (milestone) — еще один вид сущностей в GitLab, более высокого уровня чем задачи и merge request'ы. С его помощью можно реализовать организацию последних в осмысленные группы. Примером такой группы может быть поставка (установка новой версии ПО) на определенную дату.


    GitLab так же умеет в CI/CD, но вряд ли это понадобится вам сейчас, если еще вчера код хранился на девелоперской машине. Об этом я расскажу в двух словах в отдельной главе.


    Крайне рекомендую заводить ко всему README. И самой маленькой утилите, и крупному проекту пригодится README.md. Практика документирования инструкций хоть и отнимает время, но в перспективе экономит гораздо больше. GitLab отлично отображает README как и весь остальной Markdown, позволяет удобно редактировать и коммитить его в прямо в Web-IDE.


    Примечание: да, безусловно есть опция вести проект в приватном репозитории на GitHub'е, однако это может противоречить корпоративным стандартам безопасности, есть ограничение на количество таких проектов. Собственное развертывание GitLab'а внутри организации выигрывает по многим статьям.


    Миграции БД


    Ок, мы разобрались с кодом системы, но что насчет объектов БД, таких как таблицы и хранимые процедуры? Очевидно, что хранение оригиналов скриптов в самой БД рано или поздно приведет к проблемам: либо они "разъедутся" между контурами, либо будет безвозвратно утрачена история, либо еще что-то в таком роде. На помощь придут миграции баз данных. Миграция это переход от одной структуры БД к другой без потери консистентности. Подход к организации миграций ограничен лишь фантазией и смекалкой разработчика, однако известное мне разнообразие подходов может быть классифицировано на:


    • CREATE-подход — в кодовой базе проекта вместе с основным кодом системы хранится так же полный дамп всех скриптов БД, а именно по файлу на каждую таблицу, функцию, процедуру, вью, триггер и т.д. Внутри этих файлов находятся CREATE-выражения. Эти же скрипты в момент сборки попадают в дистрибутив (возможно в преобразованном виде). В момент установки дистрибутива с помощью специального софта (например RedGate SQL Compare или SQLPackage.exe) происходит сравнение целевой БД с эталоном базы из дистрибутива, формируется разностный скрипт, который доводит БД до целевого состояния;
    • ALTER-подход — в противовес предыдущему подходу здесь хранятся только начальные скрипты создания объектов, а все изменения в них записываются как ALTER-выражения. Существует два способа организации хранения таких выражений:
      • внутри кода приложения, т.е. прямо в коде системы, а затем и в бинарнике; при запуске система проверяет версию поверх которой она ставится и догоняет ее до указанной в дистрибутиве. Пример в mattermost, ameditation;
      • снаружи в специальных файлах, например в XML-файлах в случае Liquibase (статья по теме).

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


    Хорошая статья по теме: Версионная миграция структуры базы данных: основные подходы.
    Особенности миграции базы в случае канареечных релизов: На пути к Canary (там же рассказано про этот тип релизов).


    Поставка изменений


    Примечание: альтернативный подход описан в главе про Docker.


    Итак, у Вас цивилизованно и централизованно хранится код. Но что насчет выкладки нового функционала для конечных пользователей? Способ доставки может отличаться. Например, в случае внутрикорпоративного толстого клиента (а-ля АРМ) это может быть выкладка установочного пакета в сетевую папку, а в случае сайта архив со скриптами. Важно ввести понятие дистрибутива — полноценного комплекта ПО, пригодного для распространения. Важно, что дистрибутив не должен содержать контурозависимых настроек и специфичных конфигурационных файлов. Вы должны иметь возможность "раскатать" однажды собранный дистрибутив на любой контур, и одной этой установкой сразу довести систему до зафиксированной в дистрибутиве версии, включая миграции БД, о которых мы говорили ранее.



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


    Возвращаясь к разговору про стартапы. Есть такой софт GitKraken. Я им пользовался пару месяцев, когда был в отчаянии после окончательного скатывания SourceTree в бездну багов. Так вот, мне совершенно случайно попался установочный пакет этого git-клиента, когда я практиковался в вытаскивании информации из EXE. Выяснилось, что дистрибутив собирается у конкретного пользователя на машине, в папке а-ля C:\Users\Joey\Documents\.... А выглядели они технологичными и современными.


    Продолжим тему билдсервера. На нем должно быть установлено идеальное окружение, необходимый набор инструментов и настроек, позволяющих превратить исходный код в конечный дистрибутив. Шаги, правила и команды сборки обычно настраиваются в ПО класса Jenkins, GitLab или TeamCity. В узком смысле их можно назвать системой сборки. На билдсервер нужно будет установить специальный агент, позволяющий ему взаимодействовать с системой сборки. Результатом прохождения шагов сборки обычно является т.н. артефакт (или несколько артефактов), примером такого артефакта может быть дистрибутив. Имеет смысл хранить артефакты сборки вне системы сборки, например в Nexus/Artifactory. Это поможет решить вопрос надежного хранения всех версий сборок систем.


    Версия системы


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


    • простым числовым, например 7, 25, 144;
    • составным, например 25.4, 33.1;
    • каноническим (он классический семантический), например 7.1.33 (MAJOR.MINOR.PATCH);
    • кастомным, например 7.1.33.eb4512a (в конце добавлен хэш коммита).

    Правило: ПО получает уникальный последовательный номер версии при сборке. В TeamCity, например, есть специальный build counter, автоматически инкрементирующийся счетчик, который идеально подходит для присвоения уникальных номеров. Из правила следует что:


    • не должно быть разных сборок (дистрибутивов) с одинаковым номером версии;
    • более поздняя сборка должна иметь более позндюю версию.

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


    Автоматическое развертывание


    Итак, теперь у вас создаются дистрибутивы: по кнопке или автоматически при слиянии в master-ветку. Можно, конечно, устанавливать их на целевые контура и вручную, но дальновиднее будет настроить автоматическую установку. Фактически это некоторый набор инструкций и команд, выполняющихся последовательно. При этом важно помнить, что некоторые команды требуют параметризации под целевой контур (поскольку дистрибутив контуронезависимый). Реализовать такое с помощью TeamCity, GitLab или даже python-скриптами. Я же рассмотрю кейс использования Ansible/AWX.



    Процитирую одну из статей об Ansible на Хабре:


    Ansible — это программное решение для удаленного управления конфигурациями. Оно позволяет настраивать удаленные машины. Главное его отличие от других подобных систем в том, что Ansible использует существующую инфраструктуру SSH, в то время как другие (chef, puppet, и пр.) требуют установки специального PKI-окружения.

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


    Менеджер пакетов


    Небольшое дополнение к теме билдсервера: для внешних подключаемых модулей и библиотек удобно пользоваться менеджером пакетов. Например pip для Python, nuget для C#, npm для Node.JS. Конфигурации менеджеров пакетов следует хранить в системе контроля версий вместе с основным кодом системы. В шаги сборки на билдсервере следует включить шаги по восстановлению и загрузке пакетов в соответствии с конфигурационным файлом/файлами. Так же это облегчит приход нового разработчика в команду — ему не нужно будет специальном образом настраивать свое рабочее окружение, обо всем позаботится менеджер пакетов. Единственный минус — некоторые экземпляры грешат тяжеловесностью, но с этим мало что можно поделать, пользы они все-таки приносят больше.


    Тестовые среды


    Примечание: альтернативный подход описан в главе про Docker.


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


    Стандартом индустрии является наличие трех контуров:


    • dev — разработческий контур. Роль такой песочницы для разработчиков могут выполнять даже их собственные машины;
    • test — контур тестирования (QA). Здесь специалисты по тестированию могут выполнять предрелизные проверки функционала;
    • prod — промышленный контур. Непосредственной "боевой" контур.

    Часто нужны отдельные контура для нагрузочного тестирования, опытной эксплутации, симуляционного тестирования, гостевого внешнего тестирования. В идеале каждый контур повторяет продуктивный по своим характеристикам, но имеет соответствующие среде настройки и интеграции. Управлять этим вручную довольно трудно, поэтому рекомендую использовать инструменты вроде Ansible (читайте далее), chef и др.


    Важно: на тестовых контурах нужно затереть чувствительные данные, а так же заменить пользователей и их контакты фейковыми. В противном случае вы рискуете отправлять отчеты и уведомления реальным пользователям с тестовых контуров.


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


    Автотесты


    Я намеренно не стал касаться темы unit-тестов, потому что в статье рассматривается сценарий превращения гадкого утенка в лебедя. По моему опыту неожиданное внедрение unit-тестов в проект без культуры написания тестируемого кода не принесет никаких легких побед. Напротив, создание автотестов, и неких автоматизированных сценариев проверки, поможет в короткие сроки сократить объемы ручного труда разработчиков и тестировщиков. Не могу посоветовать конкретный софт, все находится в руках QA-инженеров и разработчиков.


    Эксплуатация


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


    Логгирование


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


    Наиболее известные представители — ELK-стек и Graylog. Основной сценарий использования подразумевает разворачивание подобной системы внутри организации и дальнейшую отправку в нее логов из приложений и систем. Как правило отправка происходит по UDP, чтобы не нарушать работу приложений в случае отказа системы логгирования. В Graylog есть возможность воспользоваться т.н. стримами — онлайн-обработчами потока, которые применяются к логам сразу на входе в систему управления логами. Как пример: можно завести отдельный стрим на каждый контур.


    Мониторинг


    Держать руку на пульсе системы помогут системы мониторинга. Самый простой сценарий использования: отправлять из приложения различные метрики (время загрузки страниц и время выполнения операций, количество неудачных логинов, состояние сборщика мусора .NET CLR и так далее, все что важно и интересно разработчикам или бизнесу) и наблюдать за ними вживую на дашборде. Стандартные метрики можно получить "из коробки" установкой пакета, непосредственно отправку метрик решают библиотеки, а для метрик бизнес-логики, конечно, потребуется дописать код системы.


    Из бесплатного ПО для решения задач мониторинга я бы посоветовал Grafana. Позаимствовал список особенностей Grafana из статьи:


    • приятный внешний вид;
    • динамичное обновление всех данных;
    • визуальный конструктор;
    • подключение большого количества типов источников данных (Graphite, InfluxDB, Prometheus, Elasticsearch…);
    • множество способов аутентификации;
    • возможность отправки Alert`ов ( Slack, PagerDuty, VictorOps, OpsGenie...);
    • большое количество plugin`ов для расширения функционала.

    Отличный софт, чтобы оценить удобство и красоту стоит хотя бы раз воспользоваться.


    Контроль качества кода


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


    Sonarqube


    Проведение кодревью помогает держать кодовую базу в чистоте и порядке. Однако просмотреть весь существующий код на предмет ошибок и недостатков обычно не представляется возможным — это займет слишком много времени. Статические анализаторы кода помогут выполнить эту задачу с должным уровнем качества и практически без усилий. Рекомендую обратить внимание на бесплатный инструмент SonarQube:


    SonarQube — платформа с открытым исходным кодом для непрерывного анализа (англ. continuous inspection) и измерения качества программного кода.

    Однажды настроенный сонар может выполнять регулярные проверки качества кода в разрезе ошибок, технического долга, информационной безопасности и кода "с душком" (code smells).



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


    Стиль кодирования


    Практика фиксации единого стиля кодирования присуша многим сформировавшимся командам. Code guide, code style — это все примерно об одном и том же. Открывать ли фигурные скобки для одного выражения в if, переносить ли на новую строку каждый параметр функции, табы или пробелы — все эти необднозначности помогает решить договоренность команды о едином стиле кодирования. Единообразная кодовая база позволяет не только облегчить чтение кода участниками команды, но и понизить планку вхождения в проект новичкам.


    Линтеры — специальный класс программ, который может помочь в неуклонном соблюдении стиля кодирования. Историческая справка: Lint это имя собственное статического анализатора языка C, "который сообщал о подозрительных или непереносимых на другие платформы выражениях". Его название стало именем нарицательным для всех программ такого рода. Сейчас линтеры существует для большинства известных языков программирования: в виде отдельных утилит, плагинов для редакторов или фичей IDE. Стиль кодирования задается некоторым конфигурационным файлом, который распространяется в команде.


    Безопасность


    Тема информационной безопасности была кратко затронута в главе по SonarQube. Существуют и более продвинутые статические анализаторы кода на предмет уязвимостей, например ChechMarx. Это гибкое и настраиваное ПО поддерживает все основные языки программирования и виды уязвимостей. Механизм работы примерно следующий: в коде программы отслеживается поток данных из всех входных точек (пользовательский ввод, аргументы командной строки, данные из БД) в выходные (UI, отчеты, БД) на предмет отсутствия санитайзеров. Санитайзером называется любая функция или метод, проверяющий содержимое ввода на легитимность. Если санитайзер отсутствует, то анализатор сообщает о потенциальной уязвимости. ChechMarx так же приводит полную пошаговую цепочку преобразований данных, допускающую возможную уязвимость.


    Бесплатное ПО из этой же категории: wapiti, nikto


    Общее неинструментальное


    Большинство рекомендаций это статьи затрагивают применение специализированного ПО для улучшения того или иного аспекта процессов разработки. Однако значимая доля задач построения эффективной разработки решается не использованием софта, а применением методологий, организацией процессов и принятием соглашений о процессе.



    Методология разработки


    Использование методологий разработки помогает сделать коллективную разработку организованной. Если ранее не использовалась вообще никакая методология, то стоит задуматься об адаптации какой-либо из них. Есть большое количество статей по теме, которые помогут определиться. Мне понравились эти две: issoft.by и geekbrains.ru.


    В статье в основном факты, но в этом абзаце разбавлю материал субъективным мнением. На практике в энтерпрайзе чаще всего можно встретить водопад и различные модификации agile. Первый традиционно хаят, а второй восхваляют :) На практике и водопад может быть достаточно удобен, если обогатить его обратной связью на каждом этапе. И, например, крупные законодательные правки с фиксированной датой вступления в силу, затрагивающие сразу нескольких систем организации, проще оркестрировать в водопаде. С другой стороны, новые самостоятельные проекты бывает удобнее делать в режиме гибкой разработки, особенно если бизнес принимает в них активное участие.


    Релизы


    Планировать нагрузку на команду и управлять ожиданиями заказчика помогут релизы — приуроченные к конкретной дате изменения в ПО. Релиз можно считать кроссистемной версией, инструментом оркестрирования разработки между несколькими самостоятельными системами.


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


    Примечание: в GitLab есть специальная сущность — Release, однако для планирования релизов в agile-режиме можно использовать и Milestone'ы. Рекомендую изучить обе функциональности.


    Документация


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


    • создавать документацию до разработки (функциональные требования) либо после (техническое описание);
    • поручить создание отдельно выделенным аналитикам либо "догрузить" тестировщиков (Роберт Мартин рекомендует последнее).

    Желательно определиться с подходом "на берегу", так как описать зрелую или легаси систему с нуля может быть довольно трудно (и нужно ли, если проект успешно обходился без нее?). Самое главное свойство документации — она должна приносить пользу.


    Физически документацию можно вести рядом с кодом системы в git-репозитории (например, в MarkDown), в задачах багтрекера/agile-доски (GitLab, Jira, Redmine), в специально выделенной цiki (GitLab, Confluence), в Word-документах (в т.ч. с использованием sharepoint) и т.д. Важно иметь возможность просматривать историю изменения документации, чтобы можно было заглянуть в любой момент из прошлого проекта.


    Что дальше?


    К этому моменту процесс разработки уже нельзя назвать хаотичным: ведется история изменения кода, есть культура написания документации, организован процесс поставок изменений на целевые среды, настроено логиррование и мониторинг. Однако это только базовая организация, всегда есть куда расти. Поэтому далее рекомендую присмотреться к более продвинутым темам: CI/CD & DevOps и Docker & K8s.


    CI/CD & DevOps


    Простыми словами, CI/CD (Continuous Integration, Continuous Delivery — непрерывная интеграция и доставка) это технология автоматизации тестирования и доставки новых модулей разрабатываемого проекта заинтересованным сторонам (разработчики, аналитики, инженеры качества, конечные пользователи). Принцип действия в чем-то похож на конвейер: методика выполняет интеграционную функцию, объеденяет перечисленные ранее процессы в единую цепочку, цель которого — доставка готового продукта конечному пользователю.


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


    DevOps (Development Operation) – это набор практик для повышения эффективности процессов разработки и эксплуатации программного обеспечения за счет непрерывной интеграции и активного взаимодействия профильных специалистов с помощью инструментов автоматизации. Методология предназначена для эффективной организации процессов создания и обновления ПО и услуг.


    Специалистов по настройке CI/CI называют DevOps инженерами или просто DevOps'ами.


    Docker & K8s


    Контейнеры (Docker в частности) это большая тема, попробую покрыть её в двух словах и приправить ссылками (на Хабре много качественных материалов по теме).


    Краткая шпаргалка


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


    Базовый сценарий использования контейнеров, в общем-то, не связан с разработкой. Можно просто пользоваться готовыми образами различного ПО вместо ручной установки. Отличным примером является GitLab: его можно установить либо посредством выполнения инструкции с перекрестными ссылками, либо посредством выполнения одной команды docker. Подход с докером особенно удобен, если требуется "пощупать" сервис в пробном режиме и не тащить на машину тонны зависимостей.


    Сами по себе контейнеры уже были прорывом, однако засияли они в момент появления зрелых средств оркестрации, таких как Kubernetes. В плане разработки контейнеры предоставляют больше преимуществ для небольших сервисов (aka микросервисов) нежели монолитов. Да, придется затронуть тему микросервисов, чтобы понять преимущества докера и оркестрации контейнеров. Поверхностное сравнение архитектур:


    Монолит Микросервисы
    Создан с помощью одного языка программирования/фреймворка Каждый микросервис создается с использованием наиболее удобного и уместного языка программирования/фреймворка
    Не имеют проблем с зависимостями, одно приложение — один набор зависимостей Каждый микросервис может зависеть от своего собственного набора библиотек и даже версии ОС
    Не подразумевает горизонтального масштабирования Микросервисы часто stateless, как следствие прозрачно масштабируются горизонтально

    Подход микросервисной архитектуры требует подходящего инструментария, такого как тандем Docker и Kubernetes. Docker обеспечивает:


    • скоростное развертывание;
    • удобную изоляцию процессов;
    • минимальное потребление ресурсов;

    Kubernetes в свою очередь обеспечивает:


    • контроль ресурсов;
    • равномерное распределение нагрузки;
    • автоматическую балансировку;
    • отслеживание потребления ресурсов и их лимиты;
    • перемещение экземпляров приложения между хостами;
    • автоматическое задействование дополнительных ресурсов (при добавлении нового хоста в кластер).

    Практическое использование


    Применение контейнеризации и оркестрации может быть альтернативным подходом к решению некоторых задач, обозначенных в статье. В разделах "Поставка изменеий" и "Тестовые среды" я поставил соответствующие примечания. Например, докер-образ может быть альтернативой дистрибутиву. Развернутая в Kubernetes композиция микросервисов системы может быть альтернативой тестовому контуру. Более того, контейнеризация облечает не только боевое и тестовое развертывание, но и непосредственно разработку, так как контейнеры позволяют безболезненно воссоздавать нужную инфраструктуру даже на машине разработчика. Это сокращает цикл "изменение кода -> сборка/установка -> проверка -> повтор", и как следствие ускоряет разработку. На практике в энтерпрайзе бывает не так радужно, случаются труднопреодолимые препятствия. Вот несколько примеров навскидку:


    • некоторый софт работает только на Windows (или вовсе является оконным приложением );
    • обмен данными происходит через файлы/сетевую папку/FTP;
    • на софт требуется дорогая лицензия;
    • вендор отказывается прикладывать усилия по контейнеризации;
    • база данных версит несколько террабайт, непонятно как выделить минимально работоспособную часть.

    Держа в уме данные особенности, я не стал расписывать сценарий "Полнейший хаос -> Docker & Kubernetes" как основной.


    Заключение


    Спасибо за внимание! Буду рад дополнениям и предложениям.


    P.S. За время моей работы над статьей вышла схожая — рекомендую почитать. У меня чуть больше энтерпрайза, а там больше специфики по вебу. В целом статьи неплохо друг друга дополняют.

    Национальный расчетный депозитарий
    Доверенная среда финасового рынка

    Комментарии 7

      +1
      Добавил бы пункт по описанию задач, definition of done, юзер-стори, и.т.д.
        +1

        Мне показалось, статья описывает определенный набор инженерных практик и инструментов. Очень много GitLab) Но остался один вопрос: что такое энтерпрайз разработка?

          0

          Да, GitLab'а действительно получилось немного больше, чем ожидалось. Что скрывать — я люблю этот инструмент.
          Энтерпрайз это любая внутренняя разработка организации, т.е. в основном под свои нужды. Стиль изложения статьи обязывает раскрыть и обиходное значение: обычно под этим названием подразумевается банковский и финансовый сектор.

          +1
          мысли автора праведные, но это нельзя назвать энтерпрайзом. всего лишь набор инструментов и практик, которые не дают ни каких гарантий.
          говорю по опыту увиденных проектов: наличие всего выше перечисленного в равной степени может быть как полноценным энтерпрайзом так и сплошным легаси в перемешку с макаронами в т.ч. и совершенно не рабочим.
          Энтерпрайз — это все таки не про инструменты и практики, а про грамотное их применение.
            0

            Спасибо за обстоятельный комментарий.
            Уточню, что под энтерпрайзом (Enterprise) в данной статье подразумевается "in-house"-разработка внутри организации, о чем я писал выше пользователю funca. Так я именую область, разработку в которой можно сделать более комфортной с помощью описанных практик. Т.е. в моем понимании область не перестает называться энтерпрайзом независимо от инструментов.
            Помимо грамонтного применения важную роль в успехе мероприятий играет вовлеченность сотрудников — "из под палки" вряд ли удастся заставить команду активно вести GitLab или исправлять долг SonarQube'а.

            +1

            Вы будете смеяться, но, мне, шахтёру из забоя, ваш рассказ очень понравился. Смена закончится — непременно введу в командную строку вами предложенные три строки кода, и… Думаю, что получится)

              +1
              Спасибо за детальный перечень с указанием Зачем и Почему, больше лучших и инженерных практик в мире — лучше в мире. :)
              Напомнило: https://habr.com/ru/company/jugru/blog/159689/.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое