Принятие технических решений, процесс RFC, документирование архитектурных решений
Время освоения: ~40 минут Цель: Освоить системный подход к принятию технических и управленческих решений — от RFC процесса до ADR, от DACI матрицы до правил Безоса — чтобы команда двигалась быстро и не застревала в бесконечных обсуждениях
| Тип | Примеры | Инструмент |
|---|---|---|
| Технические | Выбор технологии, архитектуры, паттерна | ADR (Architecture Decision Record) |
| Процессные | Как делать code review, как деплоить | RFC + team agreement |
| Стратегические | Приоритеты, roadmap, распределение ресурсов | DACI + RFC |
| Роль | Кто | Ответственность |
|---|---|---|
| Driver | Тот, кто ведёт процесс | Собирает информацию, фасилитирует, следит за сроками |
| Approver | Тот, кто принимает финальное решение | Одно лицо (не комитет!) |
| Contributor | Те, кто вносят экспертизу | Дают мнение, не блокируют |
| Informed | Те, кого нужно уведомить | Получают результат, не участвуют |
| Этап | Время | Что происходит |
|---|---|---|
| Черновик | 1-3 дня | Driver пишет RFC документ |
| Обсуждение | 3-5 дней | Async комментарии от Contributors |
| Решение | 1 день | Approver принимает решение |
| ADR | 1 день | Документирование в репозитории |
Принятие решений — ключевой навык тимлида. Не потому что только вы должны решать, а потому что именно вы несёте ответственность за то, чтобы решения принимались — правильно, вовремя и прозрачно.
Типичные проблемы в командном принятии решений:
Почему это критически важно:
Принцип: Лучше принять несовершенное решение вовремя, чем идеальное — с опозданием. Скорость принятия решений — конкурентное преимущество.
Технические решения — выбор инструментов, архитектурных паттернов, технологий. Требуют технической экспертизы. Документируются в ADR.
Процессные решения — как команда работает: формат code review, ветки, деплой, ceremony. Требуют согласия команды больше, чем экспертизы. Документируются в team agreements / runbooks.
Стратегические решения — что строить, когда, с каким приоритетом. Требуют бизнес-контекста. Часто принимаются с участием product/stakeholders.
Джефф Безос ввёл разделение, которое изменило культуру принятия решений в Amazon:
Type 1 (Необратимые, "однопутные двери"):
Type 2 (Обратимые, "двусторонние двери"):
Правило: Большинство команд применяют к Type 2 решениям процесс Type 1 — и замедляются в 5-10 раз. Первый вопрос при любом решении: "Это Type 1 или Type 2?"
Безос также ввёл принцип: в принятии решения не должно участвовать больше людей, чем можно накормить двумя пиццами (6-8 человек). Больше участников не улучшают решение, а замедляют и размывают ответственность.
RFC (Request for Comments) — документ-предложение, который описывает проблему, предлагаемое решение и приглашает к обсуждению. Пришёл из мира интернет-стандартов, адаптирован для командных процессов.
Используйте RFC для:
Не нужен RFC для:
# RFC: [Название]
## Статус
Черновик / На рассмотрении / Принят / Отклонён
## Контекст
Что происходит? Какую проблему решаем? Почему сейчас?
## Предлагаемое решение
Что именно предлагаем? Как это работает?
## Альтернативы (рассмотренные и отклонённые)
Что ещё рассматривали? Почему отклонили?
## Трейд-оффы
Что мы получаем? Что теряем? Какие риски?
## Влияние
Кто затронут? Что нужно изменить? Требуется ли миграция?
## Открытые вопросы
Что ещё неясно? Что нужно исследовать?
## Решение и дата
[Заполняется Approver после обсуждения]
# RFC: Переход на Kafka для event streaming
## Статус
На рассмотрении
## Контекст
Сейчас используем RabbitMQ для внутренних событий. При росте до 10k RPS возникают задержки и сложности с масштабированием. Нужна система с высокой пропускной способностью и гарантией доставки.
## Предлагаемое решение
Перейти на Apache Kafka для всех новых event-based сервисов. RabbitMQ оставить для легковесных задач (например, email notifications).
## Альтернативы
- **RabbitMQ + clustering**: сложнее масштабировать, нет native replay
- **AWS SQS/SNS**: lock-in, дороже при высокой нагрузке
- **NATS**: нет гарантии доставки, не подходит для critical path
## Трейд-оффы
+ Высокая пропускная способность (100k+ RPS)
+ Гарантия доставки и replay
- Сложнее в эксплуатации (нужен DevOps support)
- Высокая начальная стоимость внедрения
## Влияние
- DevOps: нужно настроить кластер Kafka
- Backend: изменить клиентские библиотеки
- Frontend: не затронут
## Открытые вопросы
1. Какой SLA по доступности Kafka мы можем гарантировать?
2. Нужно ли вводить новый role для Kafka-admin?
## Решение и дата
[Ожидается Approver к 15 марта]
Consent, а не consensus: Консенсус — все согласны. Consent — никто не возражает настолько сильно, чтобы заблокировать. Стремитесь к consent, не к consensus.
Таймбокс обязателен: Установите дедлайн для комментариев. Без дедлайна RFC висит бесконечно. Рекомендуемый период: 3-5 рабочих дней.
Disagree and commit: После принятия решения — все его поддерживают и реализуют, даже если кто-то был против. Это принцип, а не подавление мнения.
Используйте DACI:
ADR — короткий документ, который фиксирует одно архитектурное решение: контекст, само решение и его последствия. Через год новый разработчик читает ADR и понимает не только "что" — но и "почему именно так".
Без ADR: "Почему у нас PostgreSQL, а не MongoDB?" — никто не помнит, у основателей спросить нельзя, решение менять страшно.
С ADR: Открываешь docs/adr/002-database-choice.md — читаешь контекст, альтернативы, трейд-оффы, решение. 5 минут — и полная ясность.
# ADR-[номер]: [Название]
**Дата**: YYYY-MM-DD
**Статус**: Proposed / Accepted / Deprecated / Superseded by ADR-XXX
## Контекст
[1-3 абзаца: ситуация, проблема, которую решаем]
## Решение
[Что именно решили. Конкретно.]
## Последствия
**Плюсы**: ...
**Минусы**: ...
**Риски**: ...
# ADR-003: Использование Redis для кэширования сессий
**Дата**: 2024-02-10
**Статус**: Accepted
## Контекст
При масштабировании до 10k одновременных пользователей сессии в памяти не работают в multi-instance окружении. Нужно внешнее хранилище.
## Решение
Redis как внешний сессионный хранилище с TTL 24 часа.
## Последствия
**Плюсы**:
- Масштабируется горизонтально
- Сессии переживают перезапуск приложения
- Поддержка pub/sub для invalidation
**Минусы**:
- Дополнительная инфраструктурная зависимость
- Нужен мониторинг Redis
**Риски**:
- Утечка данных при неправильной конфигурации
- Зависимость от одного провайдера (если используется managed Redis)
docs/adr/ (рядом с кодом — версионируется вместе с ним)Без чёткого "кто решает" команда либо тратит часы на поиск консенсуса, либо никто не решает вообще. DACI фиксирует роли до начала обсуждения — это снимает политику и ускоряет процесс.
До обсуждения: Определите Approver. Один человек. Не "команда".
| Роль | Кто | Ответственность |
|---|---|---|
| Driver | Backend Lead (Алексей) | Пишет RFC, собирает мнения, следит за сроками |
| Approver | CTO (Елена) | Финальное решение по выбору Kafka/RabbitMQ |
| Contributors | DevOps Engineer (Максим), Senior Backend (Иван) | Экспертиза по эксплуатации и производительности |
| Informed | Product Manager (Анна), Frontend Team | Получают результат, не участвуют в обсуждении |
Как это работает:
| DACI | RACI | |
|---|---|---|
| Фокус | Процесс принятия решений | Распределение задач |
| Approver/Accountable | Один человек (A) | Один человек (A) |
| Лучше использовать | Для решений | Для проектов и задач |
| Критерий | RFC | ADR |
|---|---|---|
| Цель | Получить экспертную обратную связь до принятия решения | Зафиксировать принятое решение после принятия |
| Время | До реализации | После принятия решения |
| Формат | Длинный документ с обсуждением | Короткий, факт-ориентированный |
| Автор | Driver (часто один человек) | Любой, кто фиксирует решение |
| Статус | Черновик → На рассмотрении → Принят | Proposed → Accepted |
| Когда использовать | Любое значимое изменение | Только после того, как решение принято |
💡 Правило: RFC — это процесс, ADR — это результат. RFC без ADR — решение не задокументировано. ADR без RFC — решение принято без обсуждения.
Trade-offs — не недостаток, а часть инженерного мышления. Вот как системно их взвешивать:
| Критерий | REST | GraphQL |
|---|---|---|
| Скорость разработки | Высокая (простой CRUD) | Средняя (нужно писать schema) |
| Гибкость клиента | Низкая (over-fetching) | Высокая (client-driven) |
| Сложность поддержки | Низкая | Средняя (нужно управлять schema) |
| Производительность | Высокая для простых запросов | Высокая для сложных, но есть overhead |
| Риск | Перегрузка данных для мобильных | Сложность кэширования |
Решение: Для нашего MVP — REST (скорость выхода на рынок важнее гибкости). Для будущего — планируем миграцию на GraphQL.
Если команда игнорирует RFC и принимает решения в чате — вот конкретный план действий:
.github/ISSUE_TEMPLATE/rfc.md)Когда в организации есть централизованная архитектурная группа, а команда чувствует потерю автономии — вот как найти баланс:
| Уровень воздействия | Примеры | Кто решает | Как документировать |
|---|---|---|---|
| Локальные | Выбор библиотеки внутри сервиса, формат логов | Команда | Team agreement, не RFC |
| Кросс-командные | Новый API, общий SDK, shared database | Архитектурная группа + команда | RFC + ADR |
| Стратегические | Переход на новую платформу, смена cloud provider | CTO + Engineering Leadership | RFC + Executive Approval |
| Ошибка | Почему это плохо | Как исправить |
|---|---|---|
| Решение по умолчанию: "решим консенсусом" | Комитет из 8 человек не принимает решений — размывает ответственность и замедляет в 5x | Всегда назначать одного Approver до начала обсуждения по DACI |
| Не документировать решения — "мы обсудили и договорились" | Через месяц у каждого своя версия договорённости, споры начинаются заново | Каждое значимое решение = ADR in репозитории, даже короткий |
| Применять процесс Type 1 к Type 2 решениям | Команда тратит 3 встречи на то, что можно попробовать и откатить за день | Первый вопрос: "Это обратимо?" Если да — решаем быстро, делаем эксперимент |
| RFC без таймбокса и Approver | Документ обсуждается вечно, статус "на рассмотрении" живёт месяцами | Устанавливать дедлайн 3-5 дней в начале RFC, Approver принимает решение в назначенный день |
| Решение без альтернатив: "у нас один вариант" | Нет анализа трейд-оффов, в ADR не зафиксировано почему отклонили другие пути | Всегда рассматривать минимум 2 альтернативы, включая "ничего не делать" |
| "Disagree and not commit" — саботаж решения | Кто-то был против, публично согласился, но пассивно сопротивляется реализации | Принцип disagree and commit: несогласие выражается до решения, после — поддержка обязательна |
Возьмите 5 последних решений вашей команды (или придумайте типичные). Для каждого определите:
Примеры для практики:
Выберите реальное техническое решение из вашей команды (уже принятое или предстоящее).
Напишите ADR по структуре:
Цель: Через 10 минут у вас будет реальный ADR. Разместите его в docs/adr/ — это ваш первый шаг к культуре документирования решений.
Систематический подход к принятию решений — это не бюрократия, а инструмент скорости и качества. RFC позволяет получить лучшее мнение команды без встреч. ADR сохраняет контекст для будущего. DACI снимает политику и назначает ответственность.
Ключевые выводы:
🎯 Следующий шаг: Найдите в вашей команде одно недокументированное архитектурное решение (выбор БД, фреймворка, паттерна). Напишите для него ретроспективный ADR — это займёт 20 минут и будет полезно всей команде, особенно новым участникам.
Время освоения: 40 минут Уровень: Продвинутый Для кого: Тимлиды, менеджеры, senior-разработчики
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.