EasyТеория2 min

Architecture Decision Records

Формат ADR, примеры, когда использовать и как вести архитектурный журнал решений

Что такое ADR

Architecture Decision Record (ADR) -- короткий документ, фиксирующий одно архитектурное решение: что решили, почему, какие альтернативы рассматривали и какие последствия ожидаем.

Проблема без ADR

Через 6 месяцев:
─────────────────────────────────────────────────────
Новый разработчик: "Почему мы используем RabbitMQ,
                    а не Kafka?"

Сценарий 1 (без ADR):
  Техлид: "Не помню точно... кажется, было обсуждение
           в Slack... или на встрече... поищи в Confluence..."
  Результат: Потеряны 2 дня на исследование.
             Возможно, примут другое решение.

Сценарий 2 (с ADR):
  Техлид: "Посмотри ADR-007 в репозитории."
  ADR-007: Выбрали RabbitMQ из-за low latency для
            routing задач, поддержки priority queues,
            и отсутствия потребности в replay.
  Результат: 5 минут на прочтение. Контекст понятен.
─────────────────────────────────────────────────────

Зачем нужны ADR

Проблема Решение через ADR
"Почему так сделали?" Документировано решение и причины
"Кто это решил?" Указан автор и дата
"Какие были альтернативы?" Описаны рассмотренные варианты
"Можно ли пересмотреть?" Понятен контекст и ограничения
"Актуально ли это решение?" Статус: accepted/deprecated/superseded
Знания уходят с людьми Решения остаются в репозитории

Формат ADR

Классический формат (Michael Nygard)

# ADR-NNN: Заголовок решения

## Status
Accepted | Deprecated | Superseded by ADR-XXX

## Context
Что за ситуация? Какие силы действуют?
Технические, бизнесовые, организационные факторы.

## Decision
Что решили сделать.

## Consequences
Что хорошего и плохого из этого следует.

Расширенный формат

# ADR-NNN: Заголовок решения

## Status
Accepted

## Date
2026-02-22

## Authors
@username

## Context
Описание ситуации и проблемы.

## Decision Drivers
- Фактор 1
- Фактор 2
- Фактор 3

## Considered Options
1. Вариант A
2. Вариант B
3. Вариант C

## Decision
Выбранный вариант и обоснование.

## Consequences

### Positive
- Плюс 1
- Плюс 2

### Negative
- Минус 1
- Минус 2

### Risks
- Риск 1

## Links
- Related: ADR-005
- Supersedes: ADR-002

Пример ADR: Выбор базы данных

# ADR-003: Использование PostgreSQL как основной СУБД

## Status
Accepted

## Date
2026-01-15

## Context
Мы проектируем e-commerce платформу с требованиями:
- Транзакционная целостность для заказов и платежей
- Поддержка JSON для гибких атрибутов товаров
- Полнотекстовый поиск для каталога
- Масштабирование до 10M пользователей
- Команда имеет опыт работы с PostgreSQL

## Decision Drivers
- Надёжность транзакций (ACID)
- Гибкость структуры данных
- Опыт команды
- Стоимость владения
- Поддержка сообществом

## Considered Options

### 1. PostgreSQL
- ACID-транзакции
- JSONB для гибких схем
- Full-text search встроен
- Команда знает хорошо

### 2. MySQL
- ACID-транзакции
- JSON-поддержка слабее
- FTS через отдельные движки
- Проще в настройке

### 3. MongoDB
- Гибкая схема
- Нет полноценных транзакций (multi-document)
- Команда не имеет опыта
- Horizontal scaling из коробки

## Decision
Выбираем PostgreSQL, потому что:
1. Надёжные ACID-транзакции критичны для заказов и платежей
2. JSONB закрывает потребность в гибких атрибутах товаров
3. Встроенный FTS достаточен для начального этапа
4. Команда имеет 3+ года опыта с PostgreSQL
5. Расширяемость: pgvector для будущего ML-поиска

## Consequences

### Positive
- Надёжная транзакционная обработка заказов
- Один инструмент для structured + semi-structured данных
- Быстрый старт: команда знает технологию
- Экосистема: мониторинг, бэкапы, репликация

### Negative
- Вертикальное масштабирование как основная стратегия
- Шардинг сложнее, чем в MongoDB (Citus нужен)
- При >100M записей FTS может потребовать Elasticsearch

### Risks
- При взрывном росте может потребоваться шардинг
  Mitigation: мониторинг производительности, план миграции

Пример ADR: Архитектурное решение

# ADR-007: Использование RabbitMQ для асинхронной обработки

## Status
Accepted

## Date
2026-02-10

## Context
Системе нужна асинхронная обработка для:
- Отправки email/SMS уведомлений
- Обработки загруженных изображений
- Синхронизации данных с внешними системами
Нагрузка: ~1000 msg/sec, задачи с приоритетами,
routing по типу задачи. Replay не требуется.

## Considered Options

### 1. RabbitMQ
- Зрелый, надёжный message broker
- Priority queues, routing, dead letter exchange
- Low latency (<1ms)
- Команда имеет опыт

### 2. Apache Kafka
- High throughput, event replay
- Лог-based storage
- Более сложная настройка
- Избыточен для наших задач

### 3. Redis Streams
- Простой, быстрый
- Не такой надёжный при сбоях
- Ограниченные возможности routing

## Decision
Выбираем RabbitMQ:
1. Priority queues для срочных уведомлений
2. Flexible routing через exchanges
3. Dead letter exchange для обработки ошибок
4. Replay не требуется (Kafka избыточен)
5. Команда знает RabbitMQ

## Consequences

### Positive
- Приоритизация задач из коробки
- Гибкий routing по типу задачи
- Простая обработка ошибок (DLX)

### Negative
- Нет event replay (если понадобится -- пересмотреть)
- Вертикальное масштабирование (для наших 1K msg/sec достаточно)

### Risks
- Если потребуется event sourcing → рассмотреть Kafka (ADR-XXX)

Когда создавать ADR

Нужен ADR

Решение Пример
Выбор технологии PostgreSQL vs MongoDB
Архитектурный паттерн Monolith vs Microservices
Протокол интеграции REST vs gRPC vs GraphQL
Стратегия деплоя Kubernetes vs ECS
Подход к данным Event Sourcing vs CRUD
Безопасность Способ аутентификации

НЕ нужен ADR

Решение Почему
Имя переменной Слишком мелко
Выбор CSS-фреймворка Легко заменить
Настройка линтера Конфигурация, не архитектура
Формат логов Операционное решение

Правило: ADR нужен если

┌──────────────────────────────────────────┐
│  Решение нужно документировать если:     │
│                                          │
│  1. Его трудно или дорого отменить       │
│  2. Оно влияет на несколько компонентов  │
│  3. Через 6 месяцев спросят "почему?"    │
│  4. Команда спорила о выборе             │
│  5. Есть несколько разумных альтернатив  │
└──────────────────────────────────────────┘

Жизненный цикл ADR

Статусы

Draft ──▶ Proposed ──▶ Accepted ──▶ Deprecated
                          │              │
                          │              ▼
                          │         Superseded by ADR-XXX
                          │
                          └──▶ Rejected (с причиной)
Статус Описание
Draft Черновик, ещё обсуждается
Proposed Предложен на ревью команде
Accepted Принят, действует
Deprecated Устарел, но не заменён
Superseded Заменён новым ADR
Rejected Отклонён (важно сохранить!)

Почему НЕ удалять отклонённые ADR

Отклонённый ADR ценен!

ADR-012: Переход на микросервисы (Status: Rejected)
Причина отклонения: команда из 4 человек, overhead не оправдан

Через год: команда выросла до 20 человек
→ Пересмотреть ADR-012, создать ADR-025 с новым контекстом
→ Не повторять исследование альтернатив с нуля

Где хранить ADR

Место Плюсы Минусы
Git (docs/adr/) Версионирование, code review Не видят нетехнические
Wiki (Confluence) Доступность для всех Нет code review, устаревают
Notion/Obsidian Удобный поиск Нет связи с кодом

Рекомендация

docs/
└── adr/
    ├── 0001-use-postgresql.md
    ├── 0002-rest-api-design.md
    ├── 0003-authentication-with-jwt.md
    ├── 0007-rabbitmq-for-async.md
    ├── 0012-microservices-rejected.md
    └── README.md (index всех ADR)

Инструменты для ADR

Инструмент Описание
adr-tools CLI для создания и управления ADR (bash)
Log4brains ADR с веб-интерфейсом и поиском
Markdown Просто .md файлы в Git
MADR Markdown Any Decision Records (расширенный шаблон)

Итоги

Аспект Суть
ADR Документ фиксирующий одно архитектурное решение
Формат Status, Context, Decision, Consequences
Когда Трудно отменить, влияет на архитектуру, команда спорила
Где хранить Git рядом с кодом (docs/adr/)
Не удалять Даже rejected ADR ценны как история решений
Жизненный цикл Draft → Proposed → Accepted → Deprecated/Superseded

Главное правило: ADR -- это не бюрократия. Это страховка от потери знаний. 15 минут на написание ADR экономят дни на исследование через полгода.

Проверь себя

Для какого из этих решений ADR НЕ нужен?

Какие четыре секции входят в классический формат ADR (Michael Nygard)?

Где лучше всего хранить ADR?

Почему НЕ стоит удалять отклонённые (rejected) ADR?

Какую основную проблему решают ADR?