Я работаю архитектором (Solution Architect если быть точным) в аутсорсинговой компании. В ходе работы я занимаюсь такими активностями как: дизайн и внедрение архитектурных решений, аудит систем заказчика и разного рода консультации вокруг архитектуры систем.

Иногда в разговоре с коллегами я говорю «спокойно, действуем ровно по учебнику». Но тут есть большая доля лукавства, т.к. одной книги где были бы собраны базовые принципы я так с ходу назвать не могу. По большей части это сборная солянка из разных книг, личного опыта и историй, рассказанных коллегами. Что-то освещено в одной из книг Фаулера, что-то есть в курсах от AWS.

В статье я решил собрать вместе список общих принципов, которых я стараюсь придерживаться, приступая к очередной задаче.

Сгенерированно нейросетью https://midjourney.gitbook.io/docs/
Сгенерированно нейросетью https://midjourney.gitbook.io/docs/

Идите от проблемы

Это немного смешной пункт, он должен идти под номером ноль. Я бы его не писал если бы не видел так много случаев, когда дизайн решения делался без понимания проблем, которые этот дизайн решает.

Грубо говоря, есть типовые архитектуры для разных случаев (например «трехзвенка с SPA для веб приложений»), их не так много. Если вы видите, что задача решается одной из типовых архитектур и никаких проблем или специфических особенностей нет, то на этом с дизайном архитектуры стоит остановиться.

Для лучшего понимая, приведу пример. Обсуждаю с cloud architect заказчика некую подсистему, опуская подробности, все на 100% сводится к классической архитектуре с микросервисом и синхронной записью/чтением записей в/из РСУБД. Вот буквально ничто из нефункциональных требований не указывает на то, что надо что-то изобретать более сложное. Более того есть жесткое требования синхронности. Архитектор – «нам нужна Кафка. Кафка — это круто». Я интересуюсь – «зачем тут Кафка т.е. что она такого добавит, что без нее не сделать (так сказать задаю вопрос – Чтобы что?)». Получаю в ответ «Кафка — это очень хорошая технология у меня экспертный опыт с Кафкой». Я полностью согласен с тем, что Кафка крута, но сюда то она каким боком? Можно, конечно, придумать решение с Кафкой, но зачем?

Короче, не будьте как он. Если нет проблемы которую типовая архитектура не решает – не надо ничего изобретать.

Предупреждая возможные комментарии «Может быть было требование использовать крутую модную технологию для привлечения разработчиков». Да такое бывает. Это объективный фактор, о таком надо знать, но тут такого не было.

Всегда решать конкретную проблему

Предыдущий пункт на несколько другой лад. Решать надо всегда конкретную проблему, сформулированную в деталях. Нельзя сделать всех людей счастливыми, но можно попытаться помочь конкретному человеку с конкретной проблемой. Также и с системами. Строя дизайн системы надо точно понимать какие у нас конкретные проблемы, в конкретных подробностях и сколько у нас всего проблем. Т.е. желательно иметь полный список, а не решать каждую из проблем по отдельности, по мере их появления. Внезапно, накануне релиза.

Говоря о конкретных деталях, я имею в виду, например такое: «система должна справляться с большим количеством одновременных пользователей». Это хорошее не функциональное требования, но оно бесполезно без понимания в цифрах «много это сколько конкретно» и говорим ли мы тут о спайках в несколько минут или о постоянной нагрузке часами. Опять же, что значит «справляться» – это скажем показывать latency < 3 сек для 95% пользователей или не выдавать 500-ю ошибку чаще чем раз в 5 запросов. Все это имеет большое значение при дизайне.

Приведу пример, на AMA сессии архитектурного борда был вопрос «как лучше подходить к инвалидации кэша». Без понимания конкретики ответить на вопрос нереально. Для начала надо хотя бы понимать, что это за кэш – кэш статических ассетов веб приложения или кэш пула соединений с базой данных в Apache Tomcat.

Другой способ подумать о конкретике это то, что называется «KPI & metrics of success». Иначе говоря, надо постараться понять, как выражается успешность вашего решения в как можно более четко квантифицируемых терминах

Типовая архитектура — это здорово

За десятки календарных лет и миллиарды человеко-лет, индустрия выработала типовые решения для типовых задач. Чем типовые решения хороши.

1. В них как правило нет серьезных сюрпризов. Все типовые грабли за вас уже собрали сотни миллионов людей, которые шли по этой дороге перед вами.

2. Их знает большинство разработчиков, шанс, что вашу задумку неправильно поймут заметно снижается.

3. Когда через 3 года команда полностью сменится и другие люди будут пытаться понять, что тут происходит – они не увидят ничего принципиально нового для себя. Что означает что они смогут легко включиться в работу и приносить пользу заказчику.

Знайте и любите типовые архитектуры. Каждая строчка там это боль и протраченные деньги миллионов людей, которые пробовали разные другие варианты.

Так нейросетка видит типовые решения
Так нейросетка видит типовые решения

Есть конечно у типовых решений недостаток - они типовые, несколько скучные, сюрпризов там нет и развлечься с ними как правило не получается. Впрочем заказчку лучше этот аргумент не приводить.

Проблему всегда надо решать в контексте организации

Закон Конвея гласит «Организации проектируют системы, которые копируют структуру коммуникаций в этой организации». На самом деле в наше время это не совсем так хотя бы потому, что в компаниях чей бизнес строится вокруг информационных продуктов все может быть устроено наоборот – орг структура частично копирует структуру системы.

Более широко я бы сформулировал бы так – при проектировании решения надо учитывать с какими орг структурами заказчика надо будет взаимодействовать в процессе разработки и эксплуатации решения.

Особенно если заказчик — это крупная энтерпрайз компания – изучение SDLC и PDLC процессов может принести вам много интересных открытий. Для начала надо иметь ответы на вопросы

  • Как устроены стандартные PDLC & SDLC практики.

  • С какими орг структурами внутри заказчика ваше решение будет взаимодействовать.

  • Каковы интересы и modus of operandi ключевых стейкхолдеров этих структур.

  • В рамках чьих бюджетов ваше решение будет развиваться и существовать.

Последние пункты сильно залезают на поле психологии, бюджетирования и тому подобных не инженерных вещей далеких от архитектуры. Но если есть возможность это прояснить – лучше всегда как можно четче понимать за чей счет весь этот банкет и сколько этот человек еще готов/рассчитывает потратить денег. Предлагать решение за 10+ млн тому, кто готов потратить не больше двух в принципе – так себе идея.

Есть мнение, что система всегда делается для конечных пользователей. Что в целом верно. Но по факту в корпоративном окружении от конечного пользователя конкретно вас иногда отделяет столько слоев, что этим можно пренебречь. К сожалению. Грубо говоря тут все сложно, старайтесь в каждом конкретном случае в этой сложности разобраться.

Нельзя решить проблему просто нарисовав/документировав решение

Можно написать хорошую документацию, которую один черт никто не читает. Никто не читает документацию, а те, что читают все равно делают не так, как было написано, оправдываясь тем, что они же понимают, что вот эта стрелка RPC вызова на диаграмме от Сервиса А к Сервису Б это метафора (реальный случай, они так и сказали – метафора). А на самом деле надо было делать совсем по другом, и они так и сделали. Документировать безусловно надо, но не стоит документацию переоценивать.

Имплементацию архитектуры надо лидировать. «Держать команду за руку», объяснять тонкие моменты (а тонким может неожиданно оказаться что угодно), проверять как сделано и давать советы в мутных случаях. Особенно на начальном этапе. По-другому это, к сожалению, не работает.

Это не значит, что архитектор должен заменять собой тимлида, но строить взаимодействие с командой (командами) надо. И надо делать это хорошо. Обязательно надо периодически щупать решение руками от заглядывая в код слева, на право по SDLC  от требования до мониторинга приложения, развернутого на рабочем окружении (если prod не доступен, то надо смотреть на самое старшее из доступных окружений).

Крайне желательно раз в несколько месяцев делать руками полный цикл изменения кода. Обычно это выглядит так:

  • Взять в спринте маленькую задачу на час-другой работы.

  • Написать код, протестировать, создать PR, пройти ревью, смерджить в релизную ветку.

  • Пройтись по процессу деплоя. Тут все сильно зависит от того как этот процесс устроен- важно пробежаться по всем шагам и понять как ваше конкретное изменение по ним бежит.

Это часто позволяет идентифицировать пробелы в дизайне, которые с высоты птичьего полета разглядеть невозможно.

Уточню, для чего это нужно. У вас может быть сколь угодно прекрасная архитектура на верхнем уровне, но если для того, чтобы все работало вместе, людям с лопатами на местах надо соединять две либы при помощи проволоки, лома и не скажу, чего еще, пытаясь впихнуть невпихуемое и другого варианта объективно нет, то проблема конкретно у вас в архитектуре, а не в совместимости компонентов. При этом, к сожалению, бывает так, что понять это можно только взяв лопату в руки и поработав ей хотя бы с полдня.

Дьявол в деталях

Прежде чем предлагать решение, основанное на каких-то технологиях, надо убедиться, что они работают вместе именно так как было вами задумано. Часто недостаточно сказать «возьмите библиотеку X, протокол Y и запустите на платформе P». Прежде чем делать большую ставку на какое-то решение, надо убедиться, что все компоненты работают друг с другом.

Бывает так, что у вас есть опыт и понимание как каждый из кубиков работает по отдельности, но, когда вы их собираете вместе могут быть неожиданные побочные эффекты. Для решения таких проблем есть концепция скелетного прототипа. Это скелет системы, который содержит все ее части и прокидывает один самый простой запрос (часто это «сложить а и б») через все компоненты системы с самого верха до самого низа.

Приведу пример. Меня просят помочь с интеграцией нашей команды в проект заказчика. У заказчика есть довольно подробно нарисованная система на базе BPML, GraphQL и т.д. (подробнее писать не буду вдруг они эту статью прочитают). В идеале все должно работать хорошо. Уже 4 месяца несколько команд работают над реализацией разных частей большой системы. Я начинаю задавать вопросы, выясняю, что все вместе «в сборе» никто не запускал. В центре всего находится сервер, который должен преобразовывать GraphQL в SQL. Этот сервер надо конфигурировать. Но как будет выглядеть процесс сохранение в git конфигурационных файлов 5-ю разными командами для сотен таблиц никто не думал. За две недели мы выяснили что часть библиотек работают не так как мы думали и в принципе не поддерживают ряд функций, которые нам нужны и часть кода, написанного другими командами, надо переписать.

Дьявол еще более в деталях

Когда я говорил о проблемах, которые архитектор решает, а нашей повседневной жизни где мы не строим ИТ системы Марсианских куполов-хабитатов, большинство проблем лежит в области не функциональных требований. Не все, но точно больше половины.

Сюда входит:

  • Latency.

  • Max throughput.

  • Контракт на сохранность данных/Транзакционность/Атомарность операций.

  • Отказоустойчивость/SLA/Возможность работы в multi-DC режиме.

  • И многое другое, например ограничение по количеству ключей/таблиц/коллекций для конкретного сервиса и т.д.

Надо все эти вещи понимать и уметь относительно них валидировать компоненты придуманного вами решения.

Простой пример – мы придумали сохранять электронные чеки покупок в Redis, ключ - UUID чека, значение – сам чек, Json структура размером скажем в 3 килобайта в среднем. Вопрос в какие не функциональные ограничения Redis в какой момент мы упремся? Поможет ли нам кластер? А что делать если не поможет? А если нам нужна отказоустойчивость на случай падения одного из дата центров?

Проблему надо решать на том уровне, на котором она решается

Бывает так, что запрос, с которым заказчик к вам приходит выполнить не реально. Скажем у заказчик хочет настроить Multi-Master репликацию в кластере из 20 PostgreSQL серверов и спрашивает совета – как это сделать. Сделать это скорее всего нормально нельзя никак. Но можно попытаться узнать, зачем ему такое понадобилось и подумать – нельзя ли решить проблему другим образом.

Собственно, в любом случае, даже когда решение очевидно имеет смысл, стоит отступить на шаг и подумать, а нет ли другого, более простого решения и нужно ли проблему решать в принципе.

Самый забавный случай иллюстрирующий этот аспект произошел лет 10 назад. Заказчик обсуждал с нами создание системы для решения определенной бизнес-функции.  Все шло к подписанию договора и началу разработки, пока на одном из звонков наш архитектор не спросил – «а почему вы вот так вот не поменяете бизнес процесс?», на что заказчик завис на пару минут и ответил «а точно, мне тогда система и не нужна вовсе», на чем все обсуждения закончились, нам сказали «спасибо». Но проект не случился.

Знать альтернативные варианты

Мир IT объемен и разнообразен. Одну и ту же проблему часто можно решить десятком разных способов. Причем из этого десятка три штуки откровенно плохие, три суперклассные, но каждый имеет свои плюсы и минусу. Остальные «решения идентичные настоящим», при определенных обстоятельствах работают, при определенных разрывают систему в клочья.

Часто заказчик приходит с вопросом «У меня не работает X c Y» и работа архитектора сводится к вопросу «А вы пробовали N вместо Y?» на что заказчик отвечает «N? Никогда не слышал, какая клевая шутка!»

Важно про каждый компонент решения понимать – какие есть альтернативы и какие у альтернатив достоинства, и недостатки.

Что дальше?

Чтение этой статьи не сделает из вас архитектора. Это скорее шпаргалка, на что обратить внимание работая с конкретной задачей. В качестве дальнейшего шага бы порекомендовал почитать например «The 6 Pillars of the AWS Well-Architected Framework» это тоже чеклист но под другим углом.

Ну и в целом полезно время от времени сверяться с рекомендациями по построению архитектуры от крупных облачных провайдеров. Я лично эти рекомендации воспринимаю некоторой долей скепсиса, но и совсем вредных вещей там тоже не посоветуют.

Комментарии (19)


  1. maxim_ge
    02.09.2022 00:02

    Крайне желательно раз в несколько месяцев делать руками полный цикл изменения кода. Обычно это выглядит так:
    Взять в спринте маленькую задачу на час-другой работы...

    Вы не могли бы привести пример использования такого подхода, в котором были выявлены и идентифицированы пробелы в дизайне?


    1. Semenych Автор
      02.09.2022 00:14
      +3

      Опишу случай из предыдущего проекта. Приложение в числе прочего может редактировать контакты, денормализованые данные должны асинхронно посылаться через Кафку в другой сервис который делает другая команда. Мы с ними вроде как это проговаривали и все должно быть норм.

      Делаю кусок в 40 строк кода который обогащает поля контакта перед сохранением. Начинаю тестировать. Выясняется, что соседняя команда которая это делала полный цикл end-to-end не прогоняла. Хотя по идее должна бы, но их это почему-то не беспокоит и вообще им некогда. Начинаю выяснять почему так и как мне end-to-end сделать, выясняется, что конктракт на формат записи постоянно мутирует, контракт живет в библиотеке и она меняется два раза на день, разработчики это знают, но наверх это не идет, иду выяснять, отчего все мутирует, выясняется, что данные там лежат в Элесадре (https://www.elassandra.io) и там "есть проблемы".

      Дальше в общем начинается нормальная работа с выяснением где искрит и вообще что за фигня. Но до момента, пока я не залез в код - все упорно молчали по разным причинам.


      1. RPG18
        02.09.2022 01:51

        Нас всех учат не выносить сор из избы. В текущем мире, если будешь рассказывать о проблемах, то тебя запишут в токсики.

        Это не значит, что архитектор должен заменять собой тимлида, но строить
        взаимодействие с командой (командами) надо.

        А где техлиды, старшие и ведущие разработчики, которые и отвечают за качество реализации?


        1. kamitora
          02.09.2022 05:40
          +3

          Нас всех учат не выносить сор из избы. В текущем мире, если будешь рассказывать о проблемах, то тебя запишут в токсики.

          Вы вроде бы все понимаете.

          А где техлиды, старшие и ведущие разработчики, которые и отвечают за качество реализации?

          Но в то же время демонстрируете признаки глубокого непонимания.


        1. Semenych Автор
          02.09.2022 10:22
          +1

          >Нас всех учат не выносить сор из избы. В текущем мире, если будешь рассказывать о проблемах, то тебя запишут в токсики.

          Построение архитектуры решения практически единственное место, где можно говорить о проблемах. Ну и потом, я же не для западного ресурса статью пишу. На английский язык проблема переводится как challenge

          >А где техлиды, старшие и ведущие разработчики, которые и отвечают за качество реализации?

          Вот и у меня такой же вопрос. Если серьезно на него есть два ответа, выбирайте какой больше нравится

          1. в FAANG-ах

          2. На самом деле, когда система достаточно большая, невозможно объять ее всю и если у тебя в руках молоток, то много какие части системы видятся как гвоздь. Перефразируя из разных ролей картинка немного разная и задача архитектора смотреть на задачу широко. У тех лидов и старших разработчиков задачи другие и взгляд несколько другой


      1. CrocodileRed
        04.09.2022 15:47

        Очень хороший пример и этот подход работает практически во всех областях.


    1. XaBoK
      02.09.2022 11:07
      +3

      Самый обыденный вариант - архитектура не описывает инструментарий. Сам писать какой-нибудь кусок я буду только для POC, но то что постоянно вижу на ревью - разработчики пишут кучу вспомогательных библиотек под себя и редко смотрят, что уже есть в солюшине. Так что есть дублирование примерно 50% вспомогательных фунций и всякого сахара, в котором тоже накапливаются ошибки и костыли. Очень классно, когда архитектор, видя этот зоопарк, вводит новый гайдлайн и стандаритизирует утилиты.

      Тоже самое с тестами - их пишут как говнокод, а там тоже можно дать дизайн и создать фреймворк. Разработчик смотрит на свою задачу, а архитектор на весь проект целиком.


    1. Semenych Автор
      02.09.2022 12:58
      +1

      Или вот 30 мин назад - смотрю в чате разработчики планируют использовать спринговую аннотацию @DependsOn - это прям плохой знак. Звонюсь с командой, выясняю для чего они хотят это сделать, объясняю как работат в этом месте спринг, надобность в @DependsOn отпадает.

      Если бы я их за руку не поймал бы, то это бы всплыло только в процессе ревью PR, а учитывая, что не каждый PR я просмотриваю, все же это работа лида - это могло всплыть через значительное время какой-то странной проблемой.


  1. a_nick
    02.09.2022 08:53
    +2

    Все верно и по делу, автору + за хорошие формулировки.


    1. Semenych Автор
      02.09.2022 10:23

      Спасибо


  1. XaBoK
    02.09.2022 11:20

    Предлагая альтернативы решений надо избегать ситуации, когда клиент не делает выбор сам, а переносит ответственность за это на архитектора. Помимо самого себя, в аутсорсе вы еще представляете всю свою компанию. Это оч.удобная позиция. Ведь, если выбор удачный, то тот самый менеджер со стороны клиента оденет на себя лавровый венок, а если возникнут проблемы, то "так нам посоветовали сранные специалисты из %имярек%"


    1. Semenych Автор
      02.09.2022 11:33

      Не знаю, мой опыт говорит, что когда что-то пошло не так, не важно кто предложил и как оно там все было политически сделано. Фэйл есть фэйл.


      1. XaBoK
        02.09.2022 12:38
        +2

        Фейл архитектора - это такая редкость, что больше похоже на черного лебедя, чем на риск для проекта. Архитектор обычно специалист с богатым опытом. И решение которое он предлагает - не единственно верное, а оптимальное в плане сложности и затрат в конкретном контексте и требованиях. Успех же проекта - усилия всей команды и прозрачность процессов.

        Чтоб не вращать коней в вакууме: заказчик хочет микросервисы в облаках и чтоб всё на mssql. Архитектор из консалтинга даёт типичное решение, но предлагает заменить дорогущие инстансы ms на монгу. "Экономия денег? Конечно мы за!" - говорит управляющий со стороны заказчика. Потом, конечно, выясняется, что надо обучить нюансам х разработчиков. Но опыт и команда у консалтеров есть, так что немного денег и времени - всё равно экономия огромна. Когда проект почти готов, выясняется, что у них есть отдел с тоннами инструментария и внутренних продуктов именно под ms sql enterprise. Так что либо переделывать проект либо всю их внутреннюю кухню. Официально требования в контракте никто не менял, так что "нас обманули" и вся фигня. В моей практике это не единичный случай, так что важно чтоб принятие альтернативы исходило от заказчика формально и архитектура соответствовала задокументированным решениям.


        1. Semenych Автор
          02.09.2022 12:55
          +1

          Мне кажется тут сильно зависит от компании. В моей практике всегда было так, что роль архитектора ходит по краю с ролью engineering менеджера, который отвественен вообще за все.

          Ну просто не понятно - вот я чувак с 25+ годами опыта, нарисовал архитектуру которая не может сфэлится и спокойно сижу и смотрю как группа товарищией упорно ведет проект на кладбище.

          Можно конечно сказать, что к архитектуре вопросов нет, я весь в белом. Но пофакту граница очень размыта.


          1. nikolas78
            02.09.2022 13:20
            +2

            Вот в том-то и дело, что архитекторов обычно воспринимают как «пришел-вник-рассказал-ушел», а он должен постоянно быть на проекте (как в случае с аннотацией @DependsOn). Но это слишком дорого, поэтому он сначала работает целый день, а потом только по запросу. Вот и теряется контроль за проектом.


            1. Semenych Автор
              02.09.2022 13:32

              Именно так. К счастью пока мне удавалось работать в проектах где говорят "Ну нам надо спроектировать арихитектуру и надо чтобы ты потом 2-3 месяца с нами был и потом хотя бы 2 часа в день присматривал".

              Но я понимаю, что это далеко не вся наблюдаемая вселенная.


          1. XaBoK
            02.09.2022 13:26

            Граница ожиданий очень размыта. По факту у меня никогда не было узд правления. Уж не знаю какой ваш опыт. Да, я открываю баги, пишу сториз в техдолг и спорю на совещаниях, но у меня в подчинении никого нет. Бюджета тоже нет. Так что если кто-то выше принял решение бежать к обрыву, то я максимум что могу - зажечь огни и расставить флажки в попытке предупредить остальное стадо.

            Так что я видел проекты по дороге на кладбище, которые удалось спасти переубдив менеджмент, но видел и те, которые разваливались. Политика, эго, слабоумие, а иногда и просто не удачное стечение обстоятельств.


            1. Semenych Автор
              02.09.2022 13:39

              У меня было ровно обратно. Узд правления всегда заметно больше чем хочется и приходится часть из этих рычагов акуратно выдвать людям которые более или менее в адеквате.

              Но я понимаю, что это сильно зависит от рабочего контекста. Подозреваю, что как раз в больших копорациях роль архитектора может быть сильно лимитирована.

              Хотя я видел как это сделано в одном из проектов и там вроде как архитектор вполне обладал исполнительной властью.

              Блин да что там говоить. В прошлом проекте я "уволил" тим лида одной из команд заказчика за некомпетентность.


  1. Hemml
    02.09.2022 11:25
    +8

    Маленькая байка. В самом начале нулевых я, аспирант второго года, решил немного подзаработать. Мне нужен был мопед и не хватало 500 баксов (большие деньги по тем временам). Через знакомого в IRC (тогда всё так делалось) нашлась халтурка -- надо было сделать систему по приему платежей за мобилную связь. Это сейчас можно оплатить телефон не поднимая пятую точку с дивана, а тогда надо было пойти 5 километров в гору в ближайший салон и там твои наличные конвертируются в у.е. на счету мобильного. У фирмы, которой меня сосватали, был диллерский вход на сервера всяких MTS и Билайнов, но они опасались давать его всем работникам на точках приема платежей. За пару недель я настроил им сервер на FreeBSD (линукс тогда не принимали всерьез), написал фронтенд на PHP и бэк на Perl, который пропихивал платежи на сервера операторов, имитируя веб-сессию диллерского интерфейса. Казалось бы, что тут может пойти не так? Я забыл спросить, сколько у этой фирмы точек в Москве. Нет, моя система работала как швейцарские часы. Но начал падать сервер MTS, куда мой бэк пытался запихивать все приходящие платежи в параллель)