Проблема: никто не знает, кто кого вызывает

В 2012 году биржевой брокер Knight Capital потерял $460 миллионов за 45 минут.
Причина — активация устаревшего модуля, который начал массово размещать ордера.
Отчёт SEC указал на ключевую ошибку:

«The firm failed to ensure that the deployment of new code would not interact with legacy systems in unintended ways.»

Другими словами: архитектура была непрозрачной. Никто не знал какие компоненты зависят друг от друга.

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

Почему это критично для архитекторов?

Gartner в 2022 году сообщил:

«70% организаций, использующих микросервисы, испытали по крайней мере один каскадный сбой за последний год.
Основная причина — отсутствие прозрачности зависимостей между компонентами.»

McKinsey оценивает, что компании тратят от 20% до 40% IT-бюджета на поддержку систем с плохой архитектурой.

А в 2021 году Facebook провёл 6 часов в оффлайне из-за сбоя в BGP, вызванного внутренними зависимостями.
Ущерб — $100 млн выручки, $50 млрд капитализации.

Корень проблемы: фрагментарное знание и отсутствие единой модели

Типичная ситуация:

  • В системе сотни REST-методов

  • Каждая команда знает только свои сервисы

  • Документация устаревшая или отсутствует

  • Зависимости не зафиксированы нигде

В результате:

  • Невозможно оценить влияние изменений

  • Рефакторинг превращается в лотерею

  • Новые разработчики месяцами вникают в систему

  • Архитектор работает вслепую

Решение: автоматическая генерация sequence-диаграмм из JSON

Существует способ построить актуальную, машиночитаемую, рекурсивно раскрываемую диаграмму вызовов — прямо в PlantUML, без внешних скриптов, на основе JSON-файлов, описывающих каждый метод.

Ключевая идея:
Каждый JSON-файл описывает один REST-метод, его систему и цепочку вызовов, которые он инициирует.

PlantUML с помощью встроенного !procedure и %load_json рекурсивно строит полную E2E-последовательность.

Формат данных: один файл — один метод

Файл именуется по шаблону:
<система>--<метод>.json
Например: SYSTEM2--POST /root/method.json

Содержимое:

{
    "system": "SYSTEM2",
    "name": "Название системы",
    "method": "POST /root/method",
    "sequence": [
        
            {
                "provider": "SYSTEM3",
                "method": "GET /internal/status"
            },
{
                "provider": "SYSTEM4",
                "method": "PUT /audit/log"
            }
        
    ]
}

Рабочий скрипт PlantUML: автоматическая рекурсивная сборка

Ниже — полный и рабочий скрипт PlantUML, который:

  • Загружает JSON по шаблону имени файла

  • Рекурсивно строит sequence-диаграмму

  • Активирует участников автоматически

  • Поддерживает произвольную глубину вложенности

@startuml Название процесса
title Название процесса
skinparam SequenceMessageAlign center
skinparam stereotypePosition bottom
autoactivate on

' Процедура для рекурсивного построения вызовов
!procedure $meth($from, $to, $name)
    ' Формируем имя JSON-файла: <to>--<name>.json
    !$fn = $to + "--" + $name + ".json"
    
    ' Загружаем JSON
    !local $d = %load_json($fn)
    
    ' Основной вызов
    $from -> $d.system: **$d.method**
    
    ' Рекурсивно обходим все вызовы в sequence
    !foreach $item in $d.sequence
        $meth($d.system, $item.provider, $item.method)
    !endfor
    
    ' Возврат ответа
    $from <-- $d.system
!endprocedure

' Запуск с начального вызова
$meth("SYSTEM1", "SYSTEM2", "POST /root/method")
@enduml

Как это работает?

  1. Диаграмма запускается с вызова:
    SYSTEM1 → SYSTEM2 → POST /root/method

  2. PlantUML формирует имя файла:
    SYSTEM2--POST /root/method.json — и загружает его

  3. Внутри JSON указаны вызовы:

    • SYSTEM3: GET /internal/status

    • SYSTEM4: PUT /audit/log

  4. Процедура $meth рекурсивно вызывает себя для каждого из них

  5. Результат — полная E2E-sequence диаграмма, от начала и до конца построенная автоматически

Преимущества подхода

Преимущество

Описание

Нет внешних скриптов

Всё работает внутри PlantUML

Рекурсивная сборка

Диаграмма строится до нужной глубины автоматически

Машиночитаемый источник

JSON легко генерировать, хранить, валидировать

Git-friendly

Файлы можно хранить в репозитории, отслеживать изменения

Децентрализованное описание

Каждая команда отвечает за свои JSON

Living documentation

Диаграмма всегда актуальна, если JSON обновляются

Применение: E2E-сценарии без ручного рисования

Такой подход идеален для:

  • Автоматического построения бизнес-сценариев (авторизация, создание заказа, оплата)

  • Onboarding’а разработчиков — один клик → полная картина

  • Архитектурного аудита — поиск циклов, глубоких вложенности, "хабов"

  • Интеграции в CI/CD — генерация схем при каждом коммите

Как внедрить?

  1. Стандартизируйте формат JSON
    Определите структуру: system, method, sequence

  2. Разместите JSON-файлы
    В общий репозиторий, например: /sequences/

  3. Настройте именование
    <система>--<метод>.json — важно для %load_json

  4. Создайте базовый .puml-файл
    С шаблоном процедуры и точкой входа

  5. Интегрируйте в документацию
    Генерируйте SVG/PNG и публикуйте в Confluence, GitHub Pages

Бизнес-выгода

Показатель

Эффект

Актуальность схем

100% — генерация из данных

Время на построение диаграммы

↓ с часов до секунд

Ошибки при интеграциях

↓ за счёт прозрачности

Онбординг новых разработчиков

↓ на X%

Риск каскадных сбоев

↓ при обнаружении циклов и глубоких цепочек

Заключение

С помощью встроенного функционала PlantUML — %load_json, !procedure, !foreach — можно построить самонастраивающуюся, рекурсивную, машиночитаемую систему визуализации архитектуры.

Подход:

  • Не требует внешних скриптов

  • Масштабируется на сотни сервисов

  • Поддерживает децентрализованное описание

  • Превращает JSON в интерактивную карту системы

Это не просто диаграмма. Это живая архитектурная модель, которая строит себя сама.

Материалы

Теги: #архитектура #it-архитектура #plantuml #json #sequence #микросервисы #зависимости #e2e #devops #habr #автоматизация #livingdocs