Сначала архитектура, потом код: почему сложные IT-проекты нельзя строить на авось
Модный технологический стек не спасёт плохо спроектированную систему. Микросервисы не исправят запутанную бизнес-логику. Резервная копия не гарантирует восстановление, а мониторинг бесполезен, если во время аварии никто не знает, что делать. Настоящая инженерия начинается задолго до первой строки кода — и не заканчивается после запуска продукта.
Содержание · 14 разделов
- 1. Начинать нужно не с технологий, а с бизнес-логики
- 2. Архитектура — это управление сложностью
- 3. Монолит или микросервисы: не идеология, а инженерный выбор
- 4. Как правильно выбирать технологический стек
- 5. Сложная бизнес-логика требует защиты от повторов и частичных сбоев
- 6. Отказоустойчивость — это не просто наличие резервного сервера
- 7. Резервная копия — ещё не план восстановления
- 8. Мониторинг должен показывать не только состояние серверов
- 9. Postmortem: как разбирать аварии, чтобы они не повторялись
- 10. Отказоустойчивость нужно проверять до настоящей аварии
- 11. Архитектуру необходимо документировать
- 12. Надёжность должна соответствовать цене ошибки
- 13. Как я бы выстраивал работу над сложным IT-проектом
- Вместо заключения: хороший проект — это не тот, который однажды заработал
Есть распространённая ошибка в разработке сложных цифровых продуктов: начинать проектирование с выбора технологий.
Обсуждают язык программирования, фреймворк, базу данных, очереди, облачную инфраструктуру. Сравнивают производительность, изучают рейтинги, спорят о микросервисах и монолитах. Иногда выбор стека превращается в отдельный проект, хотя сама бизнес-модель будущего продукта ещё толком не определена.
В результате команда может получить современную технологическую платформу, но не получить главного — системы, которая правильно реализует бизнес-процессы, выдерживает нагрузку, сохраняет целостность данных и позволяет безопасно развивать продукт.
Проблема не в конкретном языке или фреймворке. Проблема в последовательности решений.
Сложный IT-проект нельзя строить по принципу «сначала напишем, потом разберёмся». Чем больше в системе бизнес-правил, взаимосвязей, ролей, интеграций и денежных операций, тем дороже обходится отсутствие архитектурного мышления.
1. Начинать нужно не с технологий, а с бизнес-логики
Любая серьёзная система существует ради определённых процессов. У маркетплейса это каталог, заказы, оплата, доставка, возвраты и расчёты с продавцами. У гостиничной платформы — объекты размещения, номера, тарифы, бронирования, доступность, платежи и управление заселением. У социальной платформы — пользователи, публикации, подписки, взаимодействия, модерация и рекомендации.
Это не просто набор экранов и API-методов. Это предметная область со своими сущностями, состояниями, ограничениями и правилами.
До выбора стека необходимо ответить на несколько принципиальных вопросов:
- Какие сущности существуют в системе и как они связаны?
- Какие состояния могут принимать объекты?
- Какие действия разрешены для каждой роли?
- Какие бизнес-правила должны соблюдаться всегда?
- Какие операции изменяют финансовые или критически важные данные?
- Какие процессы выполняются синхронно, а какие могут работать в фоне?
- Что произойдёт, если операция прервётся на середине?
- Какие действия должны быть обратимыми, а какие — нет?
Особенно важно определить инварианты — условия, которые система обязана сохранять при любых обстоятельствах.
Например, одно помещение нельзя одновременно забронировать двумя клиентами на пересекающиеся даты. Нельзя провести возврат на сумму, превышающую допустимую. Нельзя списать товар со склада, если его фактически нет. Нельзя позволить пользователю выполнить действие, на которое у него отсутствуют права.
Такие правила должны существовать не только в интерфейсе. Они должны быть обеспечены архитектурой, транзакциями, ограничениями базы данных и серверной бизнес-логикой.
Если критическое правило реализовано исключительно в JavaScript на клиенте, это не правило системы. Это всего лишь ограничение интерфейса, которое можно обойти прямым запросом к API.
Архитектура начинается с понимания того, что система должна гарантировать, а не с определения того, на чём её удобнее написать.
2. Архитектура — это управление сложностью
Архитектуру иногда воспринимают как набор диаграмм, папок и абстрактных принципов. На практике её основная задача гораздо конкретнее: сделать систему управляемой по мере роста.
Пока проект небольшой, многие решения кажутся несущественными. Можно разместить большую часть логики в нескольких модулях, связать компоненты прямыми вызовами и отложить разделение ответственности.
Но со временем появляются новые роли, тарифы, сценарии, интеграции, исключения и требования. Одна операция начинает затрагивать десятки компонентов. Изменение в одном месте неожиданно ломает другое. Разработчик уже не может уверенно сказать, какие части системы будут затронуты очередным обновлением.
Это признак не просто большого объёма кода, а плохо контролируемой сложности.
Хорошая архитектура должна обеспечивать:
- понятные границы ответственности между модулями;
- минимально необходимую связанность компонентов;
- единые правила работы с данными;
- предсказуемые зависимости;
- изоляцию изменений;
- возможность тестировать отдельные части системы;
- понятные механизмы расширения.
Здесь полезны принципы предметно-ориентированного проектирования — Domain-Driven Design (DDD), разделение ответственности и ограниченные контексты (Bounded Contexts).
Например, в крупной платформе управление пользователями, платежами, бронированиями и уведомлениями может быть разделено на самостоятельные предметные области. У каждой будут собственные правила и ответственность.
Это не означает, что для каждой области нужно создавать отдельный сервер. Границы предметной модели и границы физического развёртывания — разные вещи.
Можно построить хорошо организованный монолит с чёткими модулями. И можно построить десятки микросервисов, которые образуют настолько запутанную систему зависимостей, что любое изменение превращается в рискованную операцию.
Количество сервисов само по себе не является показателем качества архитектуры.
3. Монолит или микросервисы: не идеология, а инженерный выбор
Микросервисная архитектура стала одним из самых популярных символов современной разработки. Её часто выбирают заранее, исходя из представления, что сложный проект обязательно должен состоять из множества независимых сервисов.
Но микросервисы решают определённые проблемы — и одновременно создают новые.
Они позволяют независимо развивать и масштабировать отдельные части системы, изолировать некоторые сбои, использовать разные технологические решения и распределять ответственность между командами.
Однако за это приходится платить.
Появляются сетевые взаимодействия, распределённые транзакции, задержки, повторные запросы, проблемы согласованности данных, сложная диагностика, централизованное логирование, управление версиями API и инфраструктурные расходы.
То, что в монолите было обычным вызовом функции, в распределённой системе становится сетевой операцией, которая может завершиться тайм-аутом, потерей соединения или неопределённым результатом.
Представим процесс оформления заказа. Один сервис создаёт заказ, другой резервирует товар, третий принимает оплату, четвёртый отправляет уведомление. Что произойдёт, если платёж прошёл, но ответ не дошёл до вызывающего сервиса? Что делать, если резервирование товара состоялось, а следующий этап завершился ошибкой?
В распределённой системе такие ситуации нельзя считать исключениями. Их нужно проектировать заранее.
Поэтому для многих новых продуктов разумной отправной точкой становится модульный монолит: единое приложение с чёткими внутренними границами и независимыми предметными модулями.
Он позволяет не платить преждевременно за сложность распределённой инфраструктуры, сохраняя возможность выделить отдельные компоненты в сервисы, когда для этого появятся реальные основания.
Микросервисы оправданы, когда независимое масштабирование, автономность команд, изоляция отказов или особенности предметной области действительно требуют такого разделения.
Правильная архитектура — не та, которая выглядит сложнее. Правильная архитектура — та, которая решает текущие задачи и не создаёт непропорциональных проблем при развитии продукта.
4. Как правильно выбирать технологический стек
Выбор стека должен быть следствием архитектурных и бизнес-требований, а не соревнованием популярности технологий.
При выборе языка, фреймворка, базы данных и инфраструктуры важно оценивать не только скорость разработки, но и стоимость владения системой на протяжении всего её жизненного цикла.
Я бы рассматривал несколько основных критериев.
Соответствие предметной области. Технология должна позволять удобно реализовывать необходимые бизнес-процессы, сложные состояния, транзакции, интеграции и правила доступа.
Производительность и характер нагрузки. Важно понимать, какие операции будут преобладать: чтение, запись, поиск, обработка файлов, вычисления, потоковые задачи или большое количество коротких запросов.
Надёжность экосистемы. Значение имеют зрелость библиотек, качество документации, предсказуемость обновлений, безопасность зависимостей и доступность инструментов диагностики.
Компетенции команды. Даже технически привлекательная технология может стать неудачным выбором, если у команды нет достаточного опыта, а обучение и сопровождение создают чрезмерные расходы.
Эксплуатация и масштабирование. Нужно заранее понимать, как приложение будет развёртываться, обновляться, мониториться, резервироваться и восстанавливаться.
Стоимость владения. Сюда входят не только серверы и лицензии, но и разработка, сопровождение, инфраструктура, обучение, устранение ошибок и цена технологических изменений.
Отдельного внимания заслуживает выбор базы данных.
Реляционные базы данных хорошо подходят для большого количества систем, где важны связи между сущностями, ограничения целостности и транзакции. PostgreSQL, например, предоставляет развитые механизмы транзакционной обработки, индексации, ограничений и работы со структурированными данными.
Но не каждая задача должна решаться одной базой данных. Для поиска, аналитики, полнотекстовой индексации, кэширования или обработки событий могут понадобиться специализированные компоненты.
При этом добавление каждого нового инструмента увеличивает сложность эксплуатации. Поэтому использовать отдельную технологию стоит тогда, когда её преимущества оправдывают дополнительные расходы.
То же относится к очередям, брокерам сообщений, кэшам, объектным хранилищам и поисковым движкам.
Не нужно выбирать технологию потому, что её используют крупные компании. Нужно понимать, какую конкретную проблему она решает в вашем проекте.
5. Сложная бизнес-логика требует защиты от повторов и частичных сбоев
Одна из самых опасных ошибок в разработке — считать, что бизнес-операция всегда выполняется целиком и успешно.
В реальности запрос может прерваться, пользователь может нажать кнопку несколько раз, внешний сервис может не ответить, а приложение может завершиться в середине процесса.
Особенно критичны такие ситуации для платежей, заказов, бронирований, складских операций и финансовых расчётов.
Предположим, клиент оплачивает заказ. Платёжный провайдер успешно списывает деньги, но приложение не получает ответ из-за сетевой ошибки. Пользователь повторяет запрос.
Если система не умеет распознавать повторные операции, она может попытаться списать деньги ещё раз.
Для защиты от таких сценариев применяются несколько инженерных механизмов.
Идемпотентность. Повторное выполнение одного и того же запроса не должно приводить к повторному бизнес-эффекту. Например, повторная обработка одного платёжного уведомления не должна создавать второе зачисление или второй заказ.
Транзакции. Несколько изменений данных, которые должны выполняться как единая операция, необходимо объединять в транзакции. Если критическая часть не завершилась, система должна иметь возможность откатить изменения.
Ограничения целостности. Уникальные индексы, внешние ключи, ограничения значений и другие механизмы базы данных помогают защитить данные от некорректных состояний даже при ошибках прикладного кода.
Явные состояния. Для заказа, бронирования, платежа или заявки необходимо определить допустимые переходы между состояниями. Например, оплаченный заказ не должен случайно вернуться в состояние ожидания оплаты из-за повторного запроса.
Журналирование операций. Для важных действий полезно хранить историю событий и изменений. Это помогает восстановить последовательность действий, расследовать ошибки и разбирать спорные ситуации.
В распределённых системах дополнительно применяются паттерны Saga и Transactional Outbox.
Saga помогает организовывать длительные бизнес-процессы, состоящие из нескольких локальных транзакций. Если один из этапов не удаётся выполнить, система может запустить компенсирующие действия.
Transactional Outbox позволяет надёжнее связывать изменение данных в базе с отправкой события в очередь: запись события фиксируется в той же транзакции, что и основное изменение, а отдельный обработчик доставляет его получателям.
Эти механизмы не являются универсальной защитой от всех ошибок. Их нужно правильно проектировать с учётом конкретного процесса.
Но принцип остаётся неизменным: критическая бизнес-операция должна оставаться корректной даже тогда, когда запрос повторяется, связь пропадает или один из компонентов системы временно недоступен.
6. Отказоустойчивость — это не просто наличие резервного сервера
Отказоустойчивость часто понимают слишком упрощённо: есть второй сервер, значит система защищена.
Но резервный сервер не спасёт, если оба экземпляра используют одну недоступную базу данных. Реплика не поможет, если ошибка приложения повредила данные. Балансировщик не обеспечит доступность, если все запросы упираются в один внешний сервис.
Надёжность системы определяется всей цепочкой зависимостей.
Здесь важно различать несколько понятий.
- Доступность — возможность пользователя получить работающий сервис в нужный момент.
- Надёжность — способность системы корректно выполнять свои функции на протяжении времени.
- Отказоустойчивость — способность продолжать работу или сохранять критически важные функции при отказе отдельных компонентов.
- Восстанавливаемость — способность вернуть систему в работоспособное состояние после серьёзного сбоя.
Эти свойства связаны, но не заменяют друг друга.
Например, система может быть доступной большую часть времени, но терять данные при аварии. Или сохранять данные, но требовать нескольких часов ручного восстановления.
При проектировании отказоустойчивости необходимо учитывать реальные точки отказа:
- серверы приложений;
- базы данных и реплики;
- сетевую инфраструктуру;
- файловые и объектные хранилища;
- очереди и фоновые обработчики;
- внешние API и платёжные провайдеры;
- DNS, балансировщики и другие инфраструктурные компоненты.
Для повышения устойчивости применяются разные механизмы.
Тайм-ауты не позволяют запросам бесконечно занимать ресурсы в ожидании ответа.
Ограниченные повторы помогают пережить временные сетевые ошибки, но должны учитывать тип операции и не создавать лавину повторных запросов.
Circuit Breaker временно прекращает обращения к компоненту, который систематически не отвечает, чтобы не перегружать его и не распространять отказ по всей системе.
Graceful Degradation позволяет сохранить основные функции, временно отключив второстепенные. Например, при недоступности рекомендательного сервиса пользователь всё ещё должен иметь возможность открыть каталог или выполнить основной сценарий покупки.
Изоляция ресурсов помогает не допустить, чтобы одна перегруженная подсистема лишила ресурсов остальные компоненты.
Но есть ещё один важный вопрос: что именно система должна сохранять при аварии?
Иногда правильное решение — временно остановить операцию, чем допустить некорректное списание денег или двойное бронирование. Отказоустойчивость не означает, что любая функция обязана работать любой ценой.
Для критических процессов корректность данных важнее формальной доступности.
7. Резервная копия — ещё не план восстановления
Наличие резервных копий часто создаёт ложное ощущение безопасности.
Команда видит, что база данных регулярно сохраняется, файлы копируются, а архивы лежат в отдельном хранилище. Значит, в случае аварии всё можно восстановить.
Но это предположение, а не проверенный факт.
Резервная копия может оказаться повреждённой. В ней может не быть нужных файлов. Могут отсутствовать конфигурации, секреты, сертификаты, ключи доступа или инструкции по развёртыванию. Формат бэкапа может быть несовместим с текущей версией программного обеспечения.
И главное: никто не проверял, сколько времени займёт восстановление.
Для оценки готовности к авариям используются два важных показателя.
RPO (Recovery Point Objective) — допустимая потеря данных во времени. Например, RPO в один час означает, что в случае аварии допустимо потерять не более часа изменений.
RTO (Recovery Time Objective) — целевое время восстановления. Например, RTO в два часа означает, что система должна быть возвращена в работоспособное состояние в пределах этого времени.
Эти значения необходимо определять исходя из бизнес-последствий простоя и потери данных.
Для одного продукта допустимо восстановление за сутки. Для другого даже пятнадцатиминутная недоступность может привести к серьёзным финансовым потерям.
Полноценная стратегия восстановления должна охватывать не только базу данных, но и всё, что необходимо для запуска системы:
- базы данных и журналы транзакций;
- пользовательские файлы и медиаданные;
- конфигурации и инфраструктурные шаблоны;
- необходимые секреты и ключи доступа;
- версии приложений и зависимости;
- инструкции по развёртыванию и проверке работоспособности.
Резервные копии желательно хранить отдельно от основной инфраструктуры, ограничивать к ним доступ и защищать от случайного или злонамеренного удаления. Для особо критичных данных полезны неизменяемые копии.
Но самый важный пункт — регулярные проверки восстановления.
Нужно не просто создавать резервные копии, а периодически разворачивать из них тестовую среду, проверять целостность данных, запускать приложение и убеждаться, что основные бизнес-процессы действительно работают.
Бэкап, который ни разу не использовали для успешного восстановления, — это ещё не доказательство готовности к аварии.
8. Мониторинг должен показывать не только состояние серверов
Мониторинг часто ограничивается CPU, RAM, свободным местом на диске и доступностью HTTP-эндпоинтов.
Это необходимо, но недостаточно.
Сервер может отвечать на запросы, база данных может быть доступна, а пользователи при этом не смогут оформить заказ, оплатить услугу или завершить бронирование.
Поэтому мониторинг должен охватывать несколько уровней.
Инфраструктурный уровень: нагрузка, память, диски, сеть, доступность узлов.
Прикладной уровень: ошибки, задержки, количество запросов, исключения, время ответа API.
Уровень данных: состояние соединений с базой, длительность запросов, блокировки, репликация, объём хранилищ.
Фоновые процессы: длина очередей, время обработки задач, количество повторов и необработанных сообщений.
Бизнес-уровень: количество успешно созданных заказов, завершённых бронирований, проведённых платежей и другие показатели, непосредственно отражающие работу продукта.
Для поиска причин проблем полезно сочетать метрики, структурированные логи и распределённую трассировку запросов.
Особенно важно настроить оповещения по действительно значимым событиям. Если система отправляет десятки уведомлений при каждом незначительном отклонении, команда быстро перестаёт воспринимать их всерьёз.
Хороший мониторинг должен отвечать на три вопроса:
- Что именно перестало работать?
- Насколько сильно проблема затрагивает пользователей и бизнес?
- Куда смотреть, чтобы найти причину?
Мониторинг без понятного процесса реагирования — это просто сбор данных.
9. Postmortem: как разбирать аварии, чтобы они не повторялись
Даже хорошо спроектированные системы иногда выходят из строя. Вопрос не в том, можно ли полностью исключить инциденты, а в том, насколько быстро команда способна обнаружить проблему, ограничить последствия и восстановить работу.
После серьёзного инцидента необходим postmortem — структурированный разбор произошедшего.
И здесь есть принципиально важное правило: postmortem не должен превращаться в поиск виноватого.
Формулировка «разработчик допустил ошибку» практически ничего не объясняет. Гораздо полезнее выяснить, почему эта ошибка прошла через разработку, тестирование и выпуск, почему её не обнаружили автоматически и почему система не смогла ограничить последствия.
Хороший postmortem должен включать несколько частей.
1. Описание инцидента.
Что произошло, какие компоненты затронуты, какие функции были недоступны и как это повлияло на пользователей.
2. Временную шкалу.
Когда началась проблема, когда её обнаружили, какие действия предпринимались и когда система была восстановлена.
3. Технические причины.
Какие события привели к сбою, какие зависимости оказались критическими, почему возникла ошибка и какие механизмы защиты не сработали.
4. Сопутствующие факторы.
Недостаточные тесты, отсутствие мониторинга, ошибочные предположения, сложность архитектуры, недостаток документации, неудачный процесс выпуска или недостаточная подготовка команды.
5. Действия по устранению последствий.
Что было сделано для восстановления системы и защиты данных.
6. План предотвращения повторения.
Какие изменения необходимо внести в код, архитектуру, инфраструктуру, тестирование, мониторинг и процессы эксплуатации.
У каждого корректирующего действия должны быть ответственный, срок и понятный критерий выполнения.
Важно не ограничиваться задачей «исправить ошибку». Иногда правильным решением будет добавить ограничение в базу данных, изменить порядок выполнения операций, внедрить идемпотентность, настроить дополнительное оповещение или пересмотреть архитектуру взаимодействия сервисов.
Цель postmortem — не доказать, кто ошибся, а понять, какие условия позволили инциденту произойти и что нужно изменить, чтобы снизить вероятность повторения.
При таком подходе авария становится источником инженерных знаний, а не просто неприятным эпизодом, который все стараются забыть.
10. Отказоустойчивость нужно проверять до настоящей аварии
Документация и резервные копии важны, но они не заменяют практику.
Если команда ни разу не проверяла восстановление базы данных, отключение отдельного компонента или работу системы при недоступности внешнего API, она не знает, как поведёт себя продукт в реальных условиях.
Поэтому полезно проводить регулярные учения — Game Days.
Это контролируемые сценарии, в которых команда проверяет реакцию системы и людей на различные сбои:
- остановка одного из серверов приложения;
- временная недоступность базы данных;
- отказ очереди сообщений;
- потеря связи с внешним API;
- заполнение дискового пространства;
- повреждение или потеря части данных;
- восстановление системы из резервной копии.
Такие проверки должны проводиться безопасно, с понятными границами воздействия и возможностью остановить эксперимент.
Их задача — найти слабые места до того, как их обнаружат пользователи.
Отдельно стоит проверять не только техническую часть, но и готовность команды. Кто принимает решение об откате релиза? Кто отвечает за восстановление базы? Где находятся инструкции? Кто имеет необходимые доступы? Как понять, что система действительно восстановлена?
Надёжность — это свойство не только программного обеспечения, но и процесса его эксплуатации.
11. Архитектуру необходимо документировать
Ещё одна распространённая проблема — архитектура существует только в голове нескольких разработчиков.
Пока эти люди работают над проектом, система развивается. Но при смене команды, передаче проекта или появлении новых специалистов знания начинают теряться.
Документация не должна превращаться в сотни страниц, которые никто не читает. Она должна фиксировать решения, от которых зависит развитие и эксплуатация системы.
Особенно полезны:
- схема основных компонентов и их взаимодействий;
- описание предметных областей и ключевых сущностей;
- правила работы с критическими данными;
- контракты API и событий;
- сценарии развёртывания и восстановления;
- перечень внешних зависимостей;
- инструкции по реагированию на типовые инциденты.
Для важных архитектурных решений удобно использовать ADR — Architecture Decision Records.
В ADR фиксируется проблема, рассмотренные варианты, принятое решение и причины, по которым был выбран именно этот подход.
Это помогает не только понять текущую архитектуру, но и избежать повторного обсуждения уже решённых вопросов без знания первоначального контекста.
12. Надёжность должна соответствовать цене ошибки
Можно построить систему с географически распределённой инфраструктурой, множеством реплик, резервными площадками и сложными механизмами переключения.
Но это не всегда разумно.
Каждый дополнительный уровень отказоустойчивости требует денег, времени, специалистов и эксплуатационной дисциплины. Иногда стоимость защиты от крайне редкого сценария превышает возможный ущерб от него.
Поэтому надёжность нужно проектировать с учётом критичности продукта.
Для внутреннего инструмента небольшой команды может быть достаточно регулярных резервных копий, мониторинга и понятной процедуры восстановления.
Для финансовой платформы, системы бронирования или сервиса с большим количеством критичных операций требования будут значительно выше.
Правильный вопрос не в том, насколько сложную инфраструктуру можно построить. Правильный вопрос — какие последствия бизнес готов допустить при отказе системы и сколько он готов вложить в снижение этого риска.
Это не повод экономить на безопасности и восстановлении. Это способ направлять инженерные ресурсы туда, где они действительно защищают продукт.
13. Как я бы выстраивал работу над сложным IT-проектом
Если свести всё сказанное к последовательности действий, я бы выделил девять этапов.
Первый — исследование предметной области. Определить бизнес-процессы, роли, сущности, ограничения и критические сценарии.
Второй — проектирование бизнес-логики. Описать состояния объектов, переходы, правила, исключения и инварианты.
Третий — проектирование архитектуры. Определить модули, границы ответственности, зависимости, взаимодействия и стратегию работы с данными.
Четвёртый — выбор технологического стека. Сопоставить требования проекта с возможностями технологий, компетенциями команды и стоимостью эксплуатации.
Пятый — проектирование надёжности. Определить критические точки отказа, допустимые потери данных, целевое время восстановления и необходимые механизмы защиты.
Шестой — разработка и автоматизированное тестирование. Проверять не только отдельные функции, но и бизнес-сценарии, ограничения целостности, повторные запросы и ошибочные состояния.
Седьмой — подготовка эксплуатации. Настроить развёртывание, мониторинг, логирование, резервное копирование, управление доступами и оповещения.
Восьмой — проверка восстановления. Убедиться, что резервные копии действительно позволяют вернуть систему в рабочее состояние в пределах согласованных RPO и RTO.
Девятый — постоянное развитие. Анализировать инциденты, проводить postmortem, пересматривать архитектурные решения и проверять, соответствует ли система новым требованиям.
Это не означает, что все решения нужно принять окончательно до начала разработки. Архитектура развивается вместе с продуктом. Но критические предположения необходимо проверять заранее, а важные решения — принимать осознанно.
Вместо заключения: хороший проект — это не тот, который однажды заработал
Написать приложение, которое выполняет основные функции, — важная, но только начальная часть работы.
Настоящая инженерная задача сложнее: создать систему, которую можно развивать без постоянного страха что-нибудь сломать, которая сохраняет корректность бизнес-операций при ошибках, выдерживает предсказуемые нагрузки и позволяет восстановить работу после серьёзного сбоя.
Для этого недостаточно выбрать популярный стек, использовать модный архитектурный подход или добавить несколько серверов.
Нужны продуманная предметная модель, понятные границы ответственности, корректная работа с данными, осмысленный выбор технологий, автоматизированные проверки, мониторинг, резервное копирование и отработанные процедуры восстановления.
И ещё одна вещь, о которой часто забывают: архитектура — это не документ, который однажды согласовали и положили в папку. Это последовательность решений, за которые команда отвечает на протяжении всего жизненного цикла продукта.
Сложный проект нельзя построить на авось. Чем больше денег, данных, пользователей и бизнес-процессов он объединяет, тем меньше в нём должно оставаться случайных решений.
Хорошая система — не та, которая никогда не ломается. Это система, в которой риски осознаны, ошибки обнаруживаются, последствия ограничиваются, данные защищены, а восстановление не зависит от удачи и памяти одного разработчика.
Читайте также
Кому принадлежат вычислительные мощности страны? Государство приходит в дата-центры
Серверы, облачные платформы и центры обработки данных давно перестали быть просто коммерческой инфраструктурой. На них работают банки, магазины, государственные сервисы, социальные сети и тысячи компаний. Но что происходит, когда государство получает право распоряжаться частью мощностей частных дата-центров? И где проходит граница между защитой цифровой инфраструктуры и вмешательством в частный бизнес?
ИИ не отнимает все профессии. Он меняет правила найма
Искусственный интеллект уже умеет писать тексты, создавать изображения, анализировать документы и генерировать программный код. Компании внедряют его в рабочие процессы, сотрудники учатся делегировать ему рутинные задачи, а руководители рассчитывают повысить производительность. Но за обещанием эффективности скрывается менее заметная проблема: молодым специалистам становится сложнее получить первую работу, а опытным — сохранить ценность своих навыков. Рынок труда меняется не так, как предсказывали футурологи. И, возможно, самое важное изменение происходит не с профессиями, а с самой карьерной лестницей.
Кому теперь принадлежит интернет: война за контент между авторами и искусственным интеллектом
Искусственный интеллект учится на материалах, которые годами создавали журналисты, фотографы, исследователи, разработчики и обычные пользователи. Но пока одни зарабатывают на новых технологиях, другие всё чаще задаются вопросом: почему их труд должен оставаться бесплатным?
Обсуждение
0 комментариевОбсуждение ещё не началось.
Комментарии — для подписчиков журнала.