Публикую стратегию крупного ретейлера по изменению IT-архитектуры и процессов

27 ноября 2016 г.

Программисты выкладывают код в Open Source, а мы решили выложить в открытый доступ стратегию по изменению IT-архитектуры и процессов одного из наших заказчиков.

Генеральный директор предложил опубликовать документ, который я, как IT-архитектор, написал для его компании. Он заплатил за это деньги, а теперь выкладывает в публичный доступ, потому что хочет узнать мнение IT-сообщества. Укажите нам на ошибки или подскажите чего мы не учли.

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

С чего всё началось

О заказчике:

  • Ритейл компания
  • 3 000 сотрудников, из них 50 человек в IT-отделе
  • 300 магазинов по стране

Проблема проявилась, когда SAP и другие монолитные системы перестали успевать за изменениями в бизнесе. Бизнес ожидал релизы как минимум раз в 1-2 недели, а не раз в полгода или в год. Мы искали способ привести архитектуру и процессы компании к необходимому состоянию.

Идея в том, чтобы решать каждую задачу наиболее подходящим инструментом, а не дорабатывать и кастомизировать один универсальный инструмент.

Ниже документ из Confluence заказчика:


Оглавление

1 Цели

  1. Решение бизнес-задач наиболее подходящим инструментом
  2. Реакция на изменения в бизнесе от 1 часа до 1 недели
  3. Стоимость решения сопоставима с прибылью от этого решения — окупаемость
  4. Нет зависимости от вендора, результат работы отчуждаем

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 Логика выбора инструмента

Каждый сервис — это конкретная система, которая решает бизнес-задачу. Иерархия выбора системы:

  1. Решаем на SAP только если ни один другой вариант не подходит. В ином случае, решение на SAP считается нежелательным. 
  2. Если есть готовое решение и его цена + внедрение стоит не дороже, чем польза от него — покупаем и внедряем.
  3. Если можно создать систему самим — создаем.
  4. Если решения еще не существует, то запускаем R&D активность в поиске подходов к решению подобных задач.

3 Архитектура

3.1 Цели перехода к новой архитектуре

  • Дать возможность внедрять тысячи изменений в год;
  • Разработка независимых частей делается независимо;
  • Оптимизация трудозатрат пользователей за счет удобной работы и убирания ручной работы;
  • Иметь возможность развивать инновационные приложения, которые дают серьёзные преимущества бизнесу;
  • Создавать инновации с адекватными затратами.

3.2 Принципы

  1. Объединить идею с единым интерфейсом и микросервисной архитектурой.
  2. Единый веб-интерфейс использует не монолитную инфраструктуру, а разбит на микросервисы, каждый из которых дополняет UI данными и функциями.
  3. Пользователи работают в одном окне, без привязки к конкретному сервису. Веб-приложение Корпоративного портала распределяет запросы пользователей по микросервисам. Сбор страницы для отображения происходит тоже из ряда микросервисов.
  4. Обновление данных в Корпоративном портале происходит по сигналу из шины сообщений или через REST API напрямую от микросервисов.
  5. Каждый микросервис сам заботиться об интеграции, т.е. показывает, как с ним можно интегрироваться и интегрирует существующие микросервисы. Интеграция может быть сделана через шину сообщений или REST API.
  6. Пользователи не имеют возможности перемещать данные самостоятельно, например, по средствам выгрузки в Excel в одном месте и загрузки этого Excel в другом.
  7. Портал должен быть построен так, чтобы очередной микросервис подключался через стандартные процедуры. Для этого у портала должен быть фреймворк для UI и регламентированное API. Тогда можно без крупных вложений подключать и отключать микросервисы.

3.3 Логическая архитектура

3.4 Подключение нового микросервиса

  1. Микросервис подключается к Continuous Delivery.
  2. Микросервис разворачивается в контейнере в облаке.
  3. Если сервис влияет на интерфейс пользователя, то использует стандартные стили и скрипты для создания/дополнения Корпоративного портала.
  4. Если у сервиса есть публичный API, то он должен быть описан в определенном формате в базе знаний компании.
  5. Если сервису нужно принимать события из Event bus и/или отдавать события в Event bus, то формат сообщений должен быть описан в базе знаний компании.

3.5 Физическая архитектура

Схему убрал из-за NDA

Ключевые части:

  1. Event bus — шина сообщений для интеграции. Горизонтально масштабируется под нагрузкой. Ожидается небольшая нагрузка, не больше 1К сообщений в секунду. Будет создана или на виртуальной машине, или использовано готовое облачное решение.
  2. Orchestration — стандартизованное управление контейнерами (обновление, версионность и т.п.)
  3. Continuous Delivery — набор инструментов для реализации постоянной поставки. Будет развернут или на виртуальной машине или использовано готовое облачное решение.
  4. Контейнеры — процессы, которые содержат работающие реализации микросервисов.

3.6 Стратегия разбивания монолита

Стратегия — «Удушение» http://martinfowler.com/bliki/StranglerApplication.html и http://blog.byndyu.ru/2014/01/blog-post_8.html#refactoring-strategies

3.7 Способы интеграции

При интеграции рекомендовано использовать один из способов или сразу оба:

  1. REST API (Remote Procedure Invocation) — при синхронном характере интеграции. Например, если микросервис отвечает за хранение и обработку фотографий изделий, то он открывает описание API, чтобы любой другой микросервис или ПО могли обратиться к API и получить фотографию изделия.
  2. Event bus (Messaging) — при событийном и асинхронном характере интеграции. Например, если Сервис1 завершает процесс и должен асинхронно известить об этом всех заинтересованных в результатах его работы, то Сервис1 создает событие, запаковывает в него все необходимые данные с результатами и отправляет в Event bus.

http://blog.byndyu.ru/2014/05/blog-post.html

Запрещено использовать следующие способы интеграции:

  1. Обмен файлами (File Transfer)
  2. Общая база данных (Shared Database)

Более подробно о способах интеграции, плюсах и минусах http://blog.byndyu.ru/2013/10/integration-patterns.html

4 Требования к микросервису

4.1 Принципы построения

  1. Один микросервис решает одну неделимую бизнес-задачу. Если задача слишком мала и не может использовать вне конкретного контекста, то ее надо включить в более общий микросервис. Если задача может быть использована отдельно вне конкретного контекста, то ее нужно выделить в отдельный микросервис.
  2. Единая заливка релиза — если микросервисы можно обновлять только вместе, то их нужно объединить в один микросервис. Если в микросервисе разные части можно релизить независимо, включая обновление БД, то эти части нужно разделить на отдельные микросервисы.
  3. Микросервис может зависеть только от Event bus, своего публичного API и своих способов хранения данных. Любые другие зависимости ставят под сомнение самостоятельное существование микросервиса.
  4. Публичное API не использует версионности http://martinfowler.com/articles/enterpriseREST.html#versioning
  5. При считывании данных из Event bus или API микросервис должен придерживаться шаблона Толерантный читатель http://martinfowler.com/bliki/TolerantReader.html
  6. Работа с контрактом API делается на основе Consumer-Driven Contracts http://martinfowler.com/articles/consumerDrivenContracts.html
  7. Микросервис выбирает способ хранения данных, наиболее подходящий для конкретной бизнес-задачи http://martinfowler.com/bliki/PolyglotPersistence.html

4.2 Границы применимости

TODO: Логика разделения инструментов. Например, документооборот лучше делать на системе для документооборота. Аналитика, кросс-инструментальные задачи и сводная информация в едином портале с данными из DWH и микросервисов.

4.3 Требования к встраиванию

Прежде, чем принять микросервис в инфраструктуру, он должен быть проверен по чеклисту:

  1. Запускается в контейнере
  2. Подключается к Continuous Delivery
  3. Если сервис влияет на UI Корпоративного портала, то использует стандартные стили и скрипты для создания UI
  4. Публичный API описан в базе знаний компании
  5. Формат выходных сообщений в Event bus описан в базе знаний компании
  6. Способ горизонтального масштабирования описан в базе знаний компании

4.4 Требования к UI

Для встраивания в Корпоративный портал требуется придерживаться определённых стандартов при работе с CSS и JavaScript.

4.4.1 CSS

  1. CSS-библиотека состоит из базовых стилей и компонентов. Базовые стили распространяются на весь документ. К ним относятся: типографика, сброс стилей, элементы форм, таблицы и прочее. Стили компонента отвечают только за конкретный блок.
  2. Единая палитра цветов. Все используемые цвета в компонентах должны принадлежать единой палитре цветов. Если для верстки требуется дополнительный цвет, то он должен быть внесен в палитру.
  3. Атомарность. Один компонент должен задавать внешний вид только одному логическому блоку. Если блок слишком велик, то его нужно разделить на подблоки и для каждого из них создать свой css-компонент.
  4. Кроссбраузерная верстка компонента. Сверстанный компонент должен корректно отображаться на всех современных платформах (персональный компьютер, планшет, мобильный телефон). Допускается адаптивность.
  5. Правила именования классов. Для именования классов используется БЭМ-нотация (Блок, Элемент, Модификатор). При этом имя блока должно состоять из двух слов.
  6. Каскад. Запрещается создавать css-правила для элементов, не входящих в компонент. Разрешается использование базовых стилей внутри компонента.
  7. Документирование. Для каждого компонента должен быть приложен readme.md с описанием компонента, в котором указывается назначение компонента и пример разметки.
  8. Линтинг. Верстка компонента должна проходить проверку по стилю кода с помощью Stylelint.

4.4.2 Javascript

  1. React.js. В качестве базовой библиотеки используется react.js.
  2. Атомарность. Компонент решает одну неделимую задачу. Если задача слишком велика, то компонент должен быть разбит на атомарные подкомпоненты.
  3. Переиспользуемость. Компонент не должен зависеть от внешнего контекста.
  4. Инкапсуляция. Компонент может работать только с DOM-элементами внутри своего контейнера. Допускается обращение к document.
  5. Расширяемость. Если функционала уже существующего компонента недостаточно, то стоит использовать компоненты высшего порядка.
  6. Источник данных. Для каждого компонента нужно указать источник данных.
  7. Покрытие тестами. Каждый компонент должен быть покрыт тестами (Enzyme, Jasmine, Mocha, Chai, Sinon и др).
  8. Документирование. Для каждого компонента должен быть приложен readme.md с описанием компонента, в котором указывается назначение компонента, его API и пример использования.

  9. Линтинг. Код компонента и тесты к нему должны проходить проверку по стилю с помощью ESLint.

4.4.3 Условия принятия компонента

  1. Проверка всего кода линтерами.
  2. Наличие “зеленых” тестов.

4.4.4 Инструменты

  1. React-devtools. Плагин для Chrome и Firefox, который помогает в разработке.
  2. React-CDK. React Component Development Kit.
  3. React-styleguidist. Генератор документации для компонентов на react.js.
  4. React-storybook. Окружение для разработки компонентов отдельно от основного приложения.

5 Инструменты для реализации

Описываем «вилки» для выбора каждой из частей инфраструктуры.

Концептуально мы отдаем предпочтение языкам, платформам и другим компонентам, которые:

  1. Кроссплатформенные
  2. Open Source с открытыми лицензиями (например, Apache 2.0)
  3. Бесплатные
  4. Не проприетарные

Например, мы выбираем GIT, а не VSS. TeamCity, а не TFS. PostgreSQL, а не Oracle.

5.1 Языки программирования 

  • Энтерпрайз код и бизнес-логика: C# и Java
  • Аналитика: R, Python
  • Функциональное или реалтайм: Go, Clojure
  • Веб: HTML/CSS/JavaScript + фреймворки

5.2 Реляционная СУБД

Методика выбора:

  • Есть тех. поддержка
  • Большое сообщество, широкое применение в реальности
  • Длинный путь со стабильными версиями
  • Использование в большом энтерпрайзе
  • Возможность работать в облаке

Выбор:

  1. PostgreSQL
  2. Либо облачное хранилище

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) и дают команде проекта понимание о текущем состоянии системы:

  1. Изменение кода в репозитории;
  2. Сборка последней версии – если сборка не прошла, процесс прерывается, команде возвращается лог с описанием проблемы.
  3. Запуск модульных тестов – если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы.
  4. Статический анализ кода – если качество кода на недостаточном уровне, процесс прерывается, команде возвращается лог с описанием проблемы.
  5. Создание артефактов для заливки — создается Docker-контейнер(ы), который содержит последнюю версию приложения. Результатом шага является система готовая к заливке «в один клик».

Следующие шаги запускаются при поставке изменений пользователям:

  1. Запуск интеграционных тестов – автоматически поднимается окружение для тестирования, запускаются тесты. Если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы;
  2. Запуск UI-тестов (если такие тесты есть) – автоматически поднимается окружение для тестирования, запускаются тесты. Если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы;
  3. Запуск нагрузочных тестов (если такие тесты есть) – автоматически поднимается окружение для тестирования, запускаются тесты. Если хотя бы один тест не прошел, процесс прерывается, команде возвращается лог с описанием проблемы;
  4. Ручное тестирование по тест-плану (если требуется) – инженер по качеству тестирует подготовленную на 4-м шаге версию системы по тестовым сценариям.
  5. Поставка версии на боевой сервер — если все критерии качества соблюдены, значит систему можно заливать на боевой сервер.
  6. Мониторинг системы (п. 5.8)

Используем Feature Toggle вместо Feature Branching http://martinfowler.com/articles/feature-toggles.html

6.3 Инструменты

  1. В целом к процессу применяем культуру DevOps https://en.wikipedia.org/wiki/DevOps
  2. Continuous Integration — TeamCity
  3. Анализатор — Sonar

7 Quality assurance

7.1 Цели

  • Минимизировать критические ошибки при эксплуатации
  • Минимизировать ручное тестирование
  • Находить ошибки дешево
  • Автоматизировать процесс тестирования
  • Автоматизировать анализ качества кода
  • Автоматизировать мониторинг качества сервиса

7.2 Средства достижения

  • Автоматизировать процесс тестирования
  • Автоматизировать анализ качества кода
  • Автоматизировать мониторинг качества сервиса

7.3 Реализация

Мы ограждаем себя от ошибок за счет обеспечения качества на каждом уровне приложения и анализа текущего состояния системы.

Система или микросервис должны сопровождаться:

  1. Набором модульных тестов. Процент покрытия кода тестами зависит от типа приложения:
    1. Библиотека — покрытие >90%
    2. Приложение без UI или минимальным UI (консольное) — покрытие >50%
    3. Интерфейс пользователя — разметку покрывать модульными тестами не требуется. Скрипты (например, JavaScript) — покрытие >50%
  2. Набором интеграционных тестов — покрывают основные сценарии;
  3. Если у системы есть интерфейс, то необходимо создать набор UI-тестов на основные сценарии. UI-тесты создаются на Selenium или аналоге с использованием шаблона PageObject;
  4. Набором нагрузочных тестов — запускаются перед выходом в боевое использование на среде, близкой к боевой;
  5. Набор тестовых сценариев и тест-план для сценариев, которые не автоматизированы и требуют ручного тестирования. Эти сценарии прогоняются во время регрессионного тестирования перед выходом в боевое использование;
  6. Отчет анализатора кода о том, что нет критичных ошибок;
  7. Интеграция с CD (п. 6) — все тесты и утилиты запускаются в процессе CD. В случае, если тесты не проходят или качество кода не соответствует выбранному уровню, новая версия не поступает в боевое использование;
  8. Проверка на соответствие архитектуры системы требованиями Компании;
  9. Интеграция с системой мониторинга (п. 5.8);
  10. Описана и внедрена стратегия резервного сохранения и восстановления системы в случае потери данных, падений;

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

8 Методология

Описание процесса от идеи до выбрасывания приложения в мусорку (описание каждого инструмента http://byndyusoft.com/productanalysis)

8.1 Принципы и ценности

  1. Ценности Agile http://www.agilemanifesto.org/iso/ru
  2. Принципы Agile http://www.agilemanifesto.org/iso/ru/principles.html
  3. Принципы Lean https://en.wikipedia.org/wiki/Lean_software_development#Lean_principles
  4. Решения предлагаются, исходя из бизнес-потребностей http://blog.byndyu.ru/2016/06/it.html

8.2 Реализация принципов

Конкретная реализация — Scrum:

  1. Описание Scrum http://www.scrumguides.org/scrum-guide.html
  2. Итерация длительностью одна или две недели, не больше.

Возможно в будущем часть задач и проектов пойдет по Kanban.

8.3 Описание процесса

Пять шагов процесса (видео http://blog.byndyu.ru/2016/06/agiledays-2016.html):

  1. Выявление целей и стратегии достижения с помощью Impact Mapping (IM) http://blog.byndyu.ru/2014/12/impact-mapping.html
  2. Создание Customer Journey Mapping (CJM)
  3. В случае создания приложения, где идет взаимодействие с пользователями, создаем User Story Mapping. Например, при создании мобильного приложения для ломбардов;
  4. Итеративное проектирование интерфейса, разработка API и т.п.;
  5. Оценка результата работы, ретроспектива и планирование следующего инкремента с новым знанием. Пункты 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 Платформа для инфраструктуры

Методика выбора:

  1. Инфраструктура работает годами
  2. Есть достаточные мощности
  3. Тех. поддержка
  4. SLA > 99,9% с гарантией
  5. Международное присутствие
  6. Наличие API для автоматизации
  7. Наличие инструментов для работы

Уже 4 месяца компания живет по этому документу, полёт нормальный. А я жду от вас комментарии.

Комментариев нет:

Отправить комментарий

Моя книга «Антихрупкость в IT»

Как достигать результатов в IT-проектах в условиях неопределённости. Подробнее...