Программисты выкладывают код в Open Source, а мы решили выложить в открытый доступ стратегию по изменению IT-архитектуры и процессов одного из наших заказчиков.
Генеральный директор предложил опубликовать документ, который я, как IT-архитектор, написал для его компании. Он заплатил за это деньги, а теперь выкладывает в публичный доступ, потому что хочет узнать мнение IT-сообщества. Укажите нам на ошибки или подскажите чего мы не учли.
Документ содержит набор концепций, по которым компания заказчика будет жить ближайшие годы. В документе вы найдете принципы построения микросервисной архитектуры, отказ от монолита и изменения в культуре компании.
С чего всё началось
О заказчике:
- Ритейл компания
- 3 000 сотрудников, из них 50 человек в IT-отделе
- 300 магазинов по стране
Проблема проявилась, когда SAP и другие монолитные системы перестали успевать за изменениями в бизнесе. Бизнес ожидал релизы как минимум раз в 1-2 недели, а не раз в полгода или в год. Мы искали способ привести архитектуру и процессы компании к необходимому состоянию.
Идея в том, чтобы решать каждую задачу наиболее подходящим инструментом, а не дорабатывать и кастомизировать один универсальный инструмент.
Ниже документ из Confluence заказчика:
Оглавление
- 1 Цели
- 2 Основные идеи
- 3 Архитектура
- 4 Требования к микросервису
- 5 Инструменты для реализации
- 6 Continuous Delivery (CD)
- 7 Quality assurance
- 8 Методология
- 9 Платформа для инфраструктуры
1 Цели
- Решение бизнес-задач наиболее подходящим инструментом
- Реакция на изменения в бизнесе от 1 часа до 1 недели
- Стоимость решения сопоставима с прибылью от этого решения — окупаемость
- Нет зависимости от вендора, результат работы отчуждаем
2 Основные идеи
Архитектура основана на микросервисах — http://martinfowler.com/articles/microservices.html
Основные идеи:
- Componentization via Services — сервис является независимым, неделимым компонентом системы
- Organized around Business Capabilities — один сервис решает одну бизнес-задачу. Это делает сервисы повторно используемыми
- Products not Projects — каждый сервис нужно воспринимать как отдельный IT-продукт и подходить к его созданию как к созданию продукта, а не проекта. Подробнее в описании процесса ниже.
- Smart endpoints and dumb pipes — точка контакта сервиса должна быть «умной», чтобы система оставалась стабильной при изменениях сервисов. Подсистема передачи данных (например, очереди) должны иметь минимум бизнес-логики, иначе со временем они станут узким местом системы.
- Decentralized Governance — «не все проблемы гвозди и не все решения молотки», решения выбираются в зависимости от специфики проблемы.
- Decentralized Data Management — единого хранилища данных быть не должно, т.к. это делать все сервисы взаимозависимыми и ограничивает в выборе инструментов для решения бизнес-задач.
- Infrastructure Automation — при большом количестве сервисов и высокой скорости изменений любые ручные действия приводят к ошибкам и высокой зависимости от человеческого фактора. Настройка Continuous Delivery – обязательная практика для текущего подхода.
- Design for failure — каждый сервис толерантен к ошибкам системы. Сервис должен работать, даже если вся остальная система не работает.
- Evolutionary Design — правильно «разрезать» монолитную систему на сервисы с одного захода практически невозможно. Поэтому делить нужно постепенно, выделяя функции монолита, которые независимо заменяемы и независимо обновляемы, т.е. замена или переписывание сервиса не затронут других сервисов, баз данных т.д.
2.1 Логика выбора инструмента
Каждый сервис — это конкретная система, которая решает бизнес-задачу. Иерархия выбора системы:
- Решаем на SAP только если ни один другой вариант не подходит. В ином случае, решение на SAP считается нежелательным.
- Если есть готовое решение и его цена + внедрение стоит не дороже, чем польза от него — покупаем и внедряем.
- Если можно создать систему самим — создаем.
- Если решения еще не существует, то запускаем R&D активность в поиске подходов к решению подобных задач.
3 Архитектура
3.1 Цели перехода к новой архитектуре
- Дать возможность внедрять тысячи изменений в год;
- Разработка независимых частей делается независимо;
- Оптимизация трудозатрат пользователей за счет удобной работы и убирания ручной работы;
- Иметь возможность развивать инновационные приложения, которые дают серьёзные преимущества бизнесу;
- Создавать инновации с адекватными затратами.
3.2 Принципы
- Объединить идею с единым интерфейсом и микросервисной архитектурой.
- Единый веб-интерфейс использует не монолитную инфраструктуру, а разбит на микросервисы, каждый из которых дополняет UI данными и функциями.
- Пользователи работают в одном окне, без привязки к конкретному сервису. Веб-приложение Корпоративного портала распределяет запросы пользователей по микросервисам. Сбор страницы для отображения происходит тоже из ряда микросервисов.
- Обновление данных в Корпоративном портале происходит по сигналу из шины сообщений или через REST API напрямую от микросервисов.
- Каждый микросервис сам заботиться об интеграции, т.е. показывает, как с ним можно интегрироваться и интегрирует существующие микросервисы. Интеграция может быть сделана через шину сообщений или REST API.
- Пользователи не имеют возможности перемещать данные самостоятельно, например, по средствам выгрузки в Excel в одном месте и загрузки этого Excel в другом.
- Портал должен быть построен так, чтобы очередной микросервис подключался через стандартные процедуры. Для этого у портала должен быть фреймворк для UI и регламентированное API. Тогда можно без крупных вложений подключать и отключать микросервисы.
3.3 Логическая архитектура
3.4 Подключение нового микросервиса
- Микросервис подключается к Continuous Delivery.
- Микросервис разворачивается в контейнере в облаке.
- Если сервис влияет на интерфейс пользователя, то использует стандартные стили и скрипты для создания/дополнения Корпоративного портала.
- Если у сервиса есть публичный API, то он должен быть описан в определенном формате в базе знаний компании.
- Если сервису нужно принимать события из Event bus и/или отдавать события в Event bus, то формат сообщений должен быть описан в базе знаний компании.
3.5 Физическая архитектура
Схему убрал из-за NDA
Ключевые части:
- Event bus — шина сообщений для интеграции. Горизонтально масштабируется под нагрузкой. Ожидается небольшая нагрузка, не больше 1К сообщений в секунду. Будет создана или на виртуальной машине, или использовано готовое облачное решение.
- Orchestration — стандартизованное управление контейнерами (обновление, версионность и т.п.)
- Continuous Delivery — набор инструментов для реализации постоянной поставки. Будет развернут или на виртуальной машине или использовано готовое облачное решение.
- Контейнеры — процессы, которые содержат работающие реализации микросервисов.
3.6 Стратегия разбивания монолита
Стратегия — «Удушение» http://martinfowler.com/bliki/StranglerApplication.html и http://blog.byndyu.ru/2014/01/blog-post_8.html#refactoring-strategies
3.7 Способы интеграции
При интеграции рекомендовано использовать один из способов или сразу оба:
- REST API (Remote Procedure Invocation) — при синхронном характере интеграции. Например, если микросервис отвечает за хранение и обработку фотографий изделий, то он открывает описание API, чтобы любой другой микросервис или ПО могли обратиться к API и получить фотографию изделия.
- Event bus (Messaging) — при событийном и асинхронном характере интеграции. Например, если Сервис1 завершает процесс и должен асинхронно известить об этом всех заинтересованных в результатах его работы, то Сервис1 создает событие, запаковывает в него все необходимые данные с результатами и отправляет в Event bus.
http://blog.byndyu.ru/2014/05/blog-post.html
Запрещено использовать следующие способы интеграции:
- Обмен файлами (File Transfer)
- Общая база данных (Shared Database)
Более подробно о способах интеграции, плюсах и минусах http://blog.byndyu.ru/2013/10/integration-patterns.html
4 Требования к микросервису
4.1 Принципы построения
- Один микросервис решает одну неделимую бизнес-задачу. Если задача слишком мала и не может использовать вне конкретного контекста, то ее надо включить в более общий микросервис. Если задача может быть использована отдельно вне конкретного контекста, то ее нужно выделить в отдельный микросервис.
- Единая заливка релиза — если микросервисы можно обновлять только вместе, то их нужно объединить в один микросервис. Если в микросервисе разные части можно релизить независимо, включая обновление БД, то эти части нужно разделить на отдельные микросервисы.
- Микросервис может зависеть только от Event bus, своего публичного API и своих способов хранения данных. Любые другие зависимости ставят под сомнение самостоятельное существование микросервиса.
- Публичное API не использует версионности http://martinfowler.com/articles/enterpriseREST.html#versioning
- При считывании данных из Event bus или API микросервис должен придерживаться шаблона Толерантный читатель http://martinfowler.com/bliki/TolerantReader.html
- Работа с контрактом API делается на основе Consumer-Driven Contracts http://martinfowler.com/articles/consumerDrivenContracts.html
- Микросервис выбирает способ хранения данных, наиболее подходящий для конкретной бизнес-задачи http://martinfowler.com/bliki/PolyglotPersistence.html
4.2 Границы применимости
TODO: Логика разделения инструментов. Например, документооборот лучше делать на системе для документооборота. Аналитика, кросс-инструментальные задачи и сводная информация в едином портале с данными из DWH и микросервисов.
4.3 Требования к встраиванию
Прежде, чем принять микросервис в инфраструктуру, он должен быть проверен по чеклисту:
- Запускается в контейнере
- Подключается к Continuous Delivery
- Если сервис влияет на UI Корпоративного портала, то использует стандартные стили и скрипты для создания UI
- Публичный API описан в базе знаний компании
- Формат выходных сообщений в Event bus описан в базе знаний компании
- Способ горизонтального масштабирования описан в базе знаний компании
4.4 Требования к UI
Для встраивания в Корпоративный портал требуется придерживаться определённых стандартов при работе с CSS и JavaScript.
4.4.1 CSS
- CSS-библиотека состоит из базовых стилей и компонентов. Базовые стили распространяются на весь документ. К ним относятся: типографика, сброс стилей, элементы форм, таблицы и прочее. Стили компонента отвечают только за конкретный блок.
- Единая палитра цветов. Все используемые цвета в компонентах должны принадлежать единой палитре цветов. Если для верстки требуется дополнительный цвет, то он должен быть внесен в палитру.
- Атомарность. Один компонент должен задавать внешний вид только одному логическому блоку. Если блок слишком велик, то его нужно разделить на подблоки и для каждого из них создать свой css-компонент.
- Кроссбраузерная верстка компонента. Сверстанный компонент должен корректно отображаться на всех современных платформах (персональный компьютер, планшет, мобильный телефон). Допускается адаптивность.
- Правила именования классов. Для именования классов используется БЭМ-нотация (Блок, Элемент, Модификатор). При этом имя блока должно состоять из двух слов.
- Каскад. Запрещается создавать css-правила для элементов, не входящих в компонент. Разрешается использование базовых стилей внутри компонента.
- Документирование. Для каждого компонента должен быть приложен readme.md с описанием компонента, в котором указывается назначение компонента и пример разметки.
- Линтинг. Верстка компонента должна проходить проверку по стилю кода с помощью Stylelint.
4.4.2 Javascript
- React.js. В качестве базовой библиотеки используется react.js.
- Атомарность. Компонент решает одну неделимую задачу. Если задача слишком велика, то компонент должен быть разбит на атомарные подкомпоненты.
- Переиспользуемость. Компонент не должен зависеть от внешнего контекста.
- Инкапсуляция. Компонент может работать только с DOM-элементами внутри своего контейнера. Допускается обращение к document.
- Расширяемость. Если функционала уже существующего компонента недостаточно, то стоит использовать компоненты высшего порядка.
- Источник данных. Для каждого компонента нужно указать источник данных.
- Покрытие тестами. Каждый компонент должен быть покрыт тестами (Enzyme, Jasmine, Mocha, Chai, Sinon и др).
- Документирование. Для каждого компонента должен быть приложен readme.md с описанием компонента, в котором указывается назначение компонента, его API и пример использования.
- Линтинг. Код компонента и тесты к нему должны проходить проверку по стилю с помощью ESLint.
4.4.3 Условия принятия компонента
- Проверка всего кода линтерами.
- Наличие “зеленых” тестов.
4.4.4 Инструменты
- React-devtools. Плагин для Chrome и Firefox, который помогает в разработке.
- React-CDK. React Component Development Kit.
- React-styleguidist. Генератор документации для компонентов на react.js.
- React-storybook. Окружение для разработки компонентов отдельно от основного приложения.
5 Инструменты для реализации
Описываем «вилки» для выбора каждой из частей инфраструктуры.
Концептуально мы отдаем предпочтение языкам, платформам и другим компонентам, которые:
- Кроссплатформенные
- Open Source с открытыми лицензиями (например, Apache 2.0)
- Бесплатные
- Не проприетарные
Например, мы выбираем GIT, а не VSS. TeamCity, а не TFS. PostgreSQL, а не Oracle.
5.1 Языки программирования
- Энтерпрайз код и бизнес-логика: C# и Java
- Аналитика: R, Python
- Функциональное или реалтайм: Go, Clojure
- Веб: HTML/CSS/JavaScript + фреймворки
5.2 Реляционная СУБД
Методика выбора:
- Есть тех. поддержка
- Большое сообщество, широкое применение в реальности
- Длинный путь со стабильными версиями
- Использование в большом энтерпрайзе
- Возможность работать в облаке
Выбор:
- PostgreSQL
- Либо облачное хранилище
5.3 NoSQL
MongoDB, Redis
5.4 Очереди
Apache Kafka
5.5 Search
elasticsearch
5.6 ОС
- Windows Server — для унаследованных систем и ПО от производителей.
- Linux — отдается предпочтение. Дистрибутивы: Debian, CentOS.
Испрользуем последнюю стабильную версию ОС.
5.7 Контейнеризация
Принять за стандарт Docker https://www.docker.com
Docker на Azure есть на Ubuntu и отдельно в большом datacenter (требует лицензию) https://success.docker.com/Datacenter/Apply/Docker_Datacenter_on_Azure
Amazon позволяет работать с контейнерами https://aws.amazon.com/ru/containers/
5.8 Мониторинг
Развиваем текущий инструмент мониторинга - Icinga2. Это форк Nagios.
Условие: новый хост или сервис должен добавлять себя в мониторинг самостоятельно (ansible).
Кроме операционного мониторинга потребуется ПО "для отчетов" по продуктивным системам, вариант - SCOM.
6 Continuous Delivery (CD)
6.1 Цели
- Короткий цикл (до 1 часа) от изменения в коде до поставки готового ПО пользователям;
- Готовность системы к поставке в любое время;
- Всесторонняя автоматическая проверка качества релиза (п. 7);
- Уменьшение стоимости, времени и рисков при поставке изменений;
- Повторяемый автоматический процесс поставки изменений.
6.2 Этапы CD
Первые 5 шагов запускаются при каждом изменении кода (push в Git) и дают команде проекта понимание о текущем состоянии системы:
- Изменение кода в репозитории;
- Сборка последней версии – если сборка не прошла, процесс прерывается, команде возвращается лог с описанием проблемы.
- Запуск модульных тестов – если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы.
- Статический анализ кода – если качество кода на недостаточном уровне, процесс прерывается, команде возвращается лог с описанием проблемы.
- Создание артефактов для заливки — создается Docker-контейнер(ы), который содержит последнюю версию приложения. Результатом шага является система готовая к заливке «в один клик».
Следующие шаги запускаются при поставке изменений пользователям:
- Запуск интеграционных тестов – автоматически поднимается окружение для тестирования, запускаются тесты. Если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы;
- Запуск UI-тестов (если такие тесты есть) – автоматически поднимается окружение для тестирования, запускаются тесты. Если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы;
- Запуск нагрузочных тестов (если такие тесты есть) – автоматически поднимается окружение для тестирования, запускаются тесты. Если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы;
- Ручное тестирование по тест-плану (если требуется) – инженер по качеству тестирует подготовленную на 4-м шаге версию системы по тестовым сценариям.
- Поставка версии на боевой сервер — если все критерии качества соблюдены, значит систему можно заливать на боевой сервер.
- Мониторинг системы (п. 5.8)
Используем Feature Toggle вместо Feature Branching http://martinfowler.com/articles/feature-toggles.html
6.3 Инструменты
- В целом к процессу применяем культуру DevOps https://en.wikipedia.org/wiki/DevOps
- Continuous Integration — TeamCity
- Анализатор — Sonar
7 Quality assurance
7.1 Цели
- Минимизировать критические ошибки при эксплуатации
- Минимизировать ручное тестирование
- Находить ошибки дешево
- Автоматизировать процесс тестирования
- Автоматизировать анализ качества кода
- Автоматизировать мониторинг качества сервиса
7.2 Средства достижения
- Автоматизировать процесс тестирования
- Автоматизировать анализ качества кода
- Автоматизировать мониторинг качества сервиса
7.3 Реализация
Мы ограждаем себя от ошибок за счет обеспечения качества на каждом уровне приложения и анализа текущего состояния системы.
Система или микросервис должны сопровождаться:
-
Набором модульных тестов. Процент покрытия кода тестами зависит от типа приложения:
- Библиотека — покрытие >90%
- Приложение без UI или минимальным UI (консольное) — покрытие >50%
- Интерфейс пользователя — разметку покрывать модульными тестами не требуется. Скрипты (например, JavaScript) — покрытие >50%
- Набором интеграционных тестов — покрывают основные сценарии;
- Если у системы есть интерфейс, то необходимо создать набор UI-тестов на основные сценарии. UI-тесты создаются на Selenium или аналоге с использованием шаблона PageObject;
- Набором нагрузочных тестов — запускаются перед выходом в боевое использование на среде, близкой к боевой;
- Набор тестовых сценариев и тест-план для сценариев, которые не автоматизированы и требуют ручного тестирования. Эти сценарии прогоняются во время регрессионного тестирования перед выходом в боевое использование;
- Отчет анализатора кода о том, что нет критичных ошибок;
- Интеграция с CD (п. 6) — все тесты и утилиты запускаются в процессе CD. В случае, если тесты не проходят или качество кода не соответствует выбранному уровню, новая версия не поступает в боевое использование;
- Проверка на соответствие архитектуры системы требованиями Компании;
- Интеграция с системой мониторинга (п. 5.8);
- Описана и внедрена стратегия резервного сохранения и восстановления системы в случае потери данных, падений;
Система будет считаться готовой к эксплуатации, если она обладает всеми вышеперечисленными качествами.
8 Методология
Описание процесса от идеи до выбрасывания приложения в мусорку (описание каждого инструмента http://byndyusoft.com/productanalysis)
8.1 Принципы и ценности
- Ценности Agile http://www.agilemanifesto.org/iso/ru
- Принципы Agile http://www.agilemanifesto.org/iso/ru/principles.html
- Принципы Lean https://en.wikipedia.org/wiki/Lean_software_development#Lean_principles
- Решения предлагаются, исходя из бизнес-потребностей http://blog.byndyu.ru/2016/06/it.html
8.2 Реализация принципов
Конкретная реализация — Scrum:
- Описание Scrum http://www.scrumguides.org/scrum-guide.html
- Итерация длительностью одна или две недели, не больше.
Возможно в будущем часть задач и проектов пойдет по Kanban.
8.3 Описание процесса
Пять шагов процесса (видео http://blog.byndyu.ru/2016/06/agiledays-2016.html):
- Выявление целей и стратегии достижения с помощью Impact Mapping (IM) http://blog.byndyu.ru/2014/12/impact-mapping.html
- Создание Customer Journey Mapping (CJM)
- В случае создания приложения, где идет взаимодействие с пользователями, создаем User Story Mapping. Например, при создании мобильного приложения для ломбардов;
- Итеративное проектирование интерфейса, разработка API и т.п.;
- Оценка результата работы, ретроспектива и планирование следующего инкремента с новым знанием. Пункты 1-3 обновляются, с п. 4 продолжается работа.
8.4 Структура команды
Product Owner, его роль и границы ответственности – https://www.youtube.com/watch?v=502ILHjX9EE
Состав команды :Dev, QA, Design, DevOps
Принцип формирования команды http://martinfowler.com/bliki/OutcomeOriented.html
Размер команды 7±2 человек.
9 Платформа для инфраструктуры
Методика выбора:
- Инфраструктура работает годами
- Есть достаточные мощности
- Тех. поддержка
- SLA > 99,9% с гарантией
- Международное присутствие
- Наличие API для автоматизации
- Наличие инструментов для работы
Уже 4 месяца компания живет по этому документу, полёт нормальный. А я жду от вас комментарии.
Комментариев нет:
Отправить комментарий