$30 off During Our Annual Pro Sale. View Details »

Автогенерация архитектуры «as Code»

Автогенерация архитектуры «as Code»

Доклад на конференции Merge 2024, Руслан Сафин

Репозиторий https://github.com/Byndyusoft/aact

Бындюсофт

May 26, 2024
Tweet

More Decks by Бындюсофт

Other Decks in Technology

Transcript

  1. Технический директор и архитектор в Бындюсофт Автор и преподаватель курса

    по микросервисной архитектуре в ИТМО Член программных комитетов CodeFest, TechLeadConf и UWDC Руслан Сафин 2
  2. 3 Byndyusoft — 12 лет на рынке Создаём IT-продукты для

    на заказ. Нам доверяют ключевые сервисы, от которых зависит бизнес.
  3. ИТ-архитектура «Фундаментальная организация системы, реализованная в её компонентах, их взаимоотношениях

    друг с другом и средой и принципах, определяющих её конструкцию и развитие» © стандарт ANSI/IEEE Std 1471-2000 5
  4. — — Версионирование — Работа с ветками — Синхронизация с

    исполняемым кодом — Возможности интеграции Картинка + — Наглядность 7
  5. + — Версионирование — Работа с ветками — Синхронизация с

    исполняемым кодом — Возможности интеграции Код — — Наглядность 8
  6. + — Наглядность — Версионирование — Работа с ветками —

    Синхронизация с исполняемым кодом — Возможности интеграции Код → Картинка 9
  7. Архитектура микросервисов в PlantUML System_Ext(goods, “Goods Repo") System_Ext(stock, “Stock") Container(bff,

    “BFF", "NestJS") Container(task_repository, “Task Repo", "NestJS”) Rel(bff, goods, "Get products", “API Gateway") Rel(task_repository, stock, “Send task", $tags="async") Rel(bff, task_repository, "Get task", “REST") 12
  8. 13

  9. Преимущества архитектуры «as code» — Унификация — Полностью аналогичный работе

    с кодом процесс: — Версионирование — Ветки — PullRequest’ы — Merge — … — Возможность автоматизации 14
  10. 19

  11. Архитектура микросервисов в PlantUML System_Ext(goods, “Goods Repo") System_Ext(stock, “Stock") Container(bff,

    “BFF", "NestJS") Container(task_repository, “Task Repo", "NestJS”) Rel(bff, goods, "Get products", “API Gateway") Rel(task_repository, stock, “Send task", $tags="async") Rel(bff, task_repository, "Get task", “REST") 22
  12. — Сложность извлечения данных — Отсутствие инфраструктурных данных Откуда брать

    актуальные зависимости сервисов? Код сервисов + Первоисточник поведения сервисов 23
  13. — Нет «редких» связей — Сложность симуляции на препроде —

    Данные только после появления трафика Откуда брать актуальные зависимости сервисов? Service Mesh + Реальный трафик 24
  14. 26

  15. Откуда брать актуальные зависимости сервисов? k8s configs + Все связи,

    включая «редкие» + Бóльшая информативность + Данные не требуют трафика 27
  16. Берём данные из конфигов [ Сервис1 { [ связь1, связь2

    ] }, Сервис2 { [ связь1, связь3 ] }, ... ]
  17. Что ещё можно добавить? Всё, что есть в конфиге и

    важно отразить на архитектуре ☺ Например: • Тип и параметры связей • Параметры контейнеров • Репликация и автоскейлинг • Разделение по хостам и дата-центрам • Метрики мониторинга • … 33
  18. Сигнал о нарушении принципов: • Stable Dependencies Principle: Depend in

    the direction of stability • Stable Abstractions Principle: A component should be as abstract as it is stable 35
  19. Ещё сложности • Именование внешних систем • Направление асинхронных связей

    • Добавление отсутствующей в конфиге информации 37
  20. 40

  21. Сравниваем данные из архитектуры и конфигов [ Сервис1 { [

    связь1, связь2 ] }, Сервис2 { [ связь1, связь2 ] }, ] [ Сервис1 { [ связь1, связь3 ] }, Сервис2 { [ связь1 ] }, Сервис3 ] 41
  22. 42

  23. Пример — сопоставление списка сервисов it("finds diff in configs and

    uml containers", () => { const namesFromDeploy = deployConfigs.map((x) => x.name); const containerNamesFromPuml = containersFromPuml .filter((x) => x.type == "Container") .map((x) => x.name); expect(namesFromDeploy).toEqual(containerNamesFromPuml); }); github.com/byndyusoft/aact/blob/ac05e3217ac4bc8d621ebbd1323ac9c86a828956/test/architecture.test.ts#L43
  24. Output Container name bff ✅ Container name task_repository❌ Container name

    invoice_acl ✅ -------------------------------------------------------- First failed container name task_repository -------------------------------------------------------- FAIL test/architecture.spec.ts • Architecture › finds diff in configs and uml dependencies expect(received).toEqual(expected) // deep equality - Expected - 1 + Received + 1 Array [ “bff", - “stock", + “goods", “invoice", github.com/byndyusoft/aact/actions/runs/6603088421/job/17935846325#step:5:67 44
  25. 1. ACL (Anti-corruption Layer) Pattern За интеграцию с внешними системами

    ответственны отдельные микросервисы-адаптеры, инкапсулирующие в себе знания о внешних системах (например, об их доменных сущностях) 50
  26. 1. ACL (Anti-corruption Layer) Pattern Как протестить: 1. помечаем на

    архитектуре соответствующие микросервисы признаком «Adapter» 2. проверяем, что связи с внешними системами имеют только сервисы с таким признаком Container(goods_adapter, “Goods ACL", "NestJS", $tags="adapter") 52
  27. Проблемы архитектурных схем 0. Их отсутствие ✅ 1. Неактуальность ✅

    2. Декларативность✅ 3. Отсутствие контроля 54
  28. Предписания архитекторов могут нарушаться по незнанию или умышленно • Упавшие

    тесты отсеют нарушения по незнанию • Обязательный апрув архитектора для PR в тестах и архитектуре отсеют недобросовестные нарушения 55 Архитектурные изменения не пройдут мимо архитектора
  29. Личный опыт • 2 чел/нед разработчика • 2 чел/нед архитектора

    • 0,5 чел/нед девопса В «продакшне» несколько месяцев 56
  30. Личный опыт, решённые проблемы • Актуализировали архитектуру • Привели к

    единым конвенциям • Нашли топики кафки с продьюсерами, но без подписчиков • Нашли неиспользуемые REST-зависимости в конфигах и коде • Актуализировали понимание внешних систем • Измерили и зафиксировали архитектурный техдолг • Переключили на API Gateway все необходимые зависимости • Убрали дублирование в конфигах 57
  31. Как начать применять? 1. github.com/Byndyusoft/aact 2. Библиотека по работе с

    PlantUML (или аналогом) на вашем стэке 3. Маппинг вашего варианта InfractructureAsCode в термины архитектуры 4. Генерация и тесты 5. 💰💰💰 58
  32. Roadmap репозитория • Покрытие архитектуры тестами • Автогенерация • Инструменты

    рефакторинга микросервисной архитектуры https://github.com/Byndyusoft/aact/blob/main/roadmap.md 60
  33. Roadmap репозитория. Покрытие архитектуры тестами ✅ Покрытие тестами микросервисной архитектуры

    ✅ Покрытие тестами архитектуры модульного монолита 🟩 Добавление реализаций и примеров под разные стэки (сейчас TypeScript и C#) ⌛ Справочник принципов и паттернов проектирования (например, в формате ADR) ⌛ Примеры тестов на пункты справочника 61
  34. Roadmap репозитория. Автогенерация ✅ Автогенерация архитектурной схемы по конфигам инфраструктуры

    🟩 Автогенерация конфигов инфраструктуры по архитектурной схеме 🟩 Добавление провайдеров для различных реализаций IaC 🟩 Автогенерация и архитектурной схемы, и конфигов инфраструктуры по архитектурному решению (ADR) 64
  35. Roadmap репозитория. Инструменты рефакторинга микросервисной архитектуры 🟩 Изменение сигнатуры метода

    API (endpoint’а) 🟩 Вынос метода API (endpoint'а) микросервиса в отдельный микросервис 🟩 Inline микросервиса — поглощение микросервиса своим потребителем 65