Записки архитектора. Чек-лист

— Составь, пожалуйста, руководство по тому, как делать архитектуру.

С такой просьбой ко мне однажды обратились менеджеры по разработке софта в компании, где я работаю или работал (не хочу раскрывать время и место). И надо сказать, что сначала эта просьба меня здорово озадачила. На тему архитектуры софта написано много книг, и не самых тонких. Мне предлагается написать еще одну? Чем она будет отличаться от существующих? И зачем вообще им это?

Что касается «зачем», то здесь все было понятно. Цель у менеджеров была благая. Проектов в компании обычно больше, чем могут осилить штатные архитекторы. Идея была в том, чтобы архитектуру для небольших проектов делали либо сами менеджеры по разработке, либо старшие разработчики, а архитектор только проверял, направлял и помогал где нужно.

Цель хорошая, запрос хороший. Оставалось только понять, как оказать им конструктивную помощь, а не отправить читать книжки или не засесть писать свою.

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

Собственно, этот список я здесь и публикую.

Перед тем, как начать, я поясню, о какой архитектуре пойдет речь. «Архитектура софта» — очень широкое понятие, многоуровневое. Есть уровень отдельных компонент приложения, уровень приложения, уровень систем. Однако конкретно я, в основном, работаю на end-to-end уровне — там, где различные системы и приложения связываются в единый продукт, или «решение» (solution). Так что мой чек-лист больше относится к solutions-архитектуре, но многое из него справедливо для архитектуры любого уровня.

Теперь поехали!

1. Определите зоны ответственности всех новых компонент (сервисов, приложений и т.п.)

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

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

Если вы умеете хорошо справляться с тремя пунктами выше, то вы уже крутой архитектор. Ибо это 90% успеха. Если у вас есть эти 90%, то дела у вас уже идут очень даже не плохо. Даже если у вас в компании используются устаревшие или неоптимальные технологии. Даже если вы все еще разрабатываете монолиты, а не микросервисы. Даже если REST-протоколы в компании реализуют на чистом Си. У вас всё равно всё будет круто. Правда, с одной оговоркой: вы должны уметь быстро выводить в продакшн новый функционал либо исправления для уже имеющегося (мы поговорим об этом как-нибудь в другой раз). И когда я говорю про 90% успеха, то на 100% серьезен. Я видел правильные «монолиты», в которые легко добавлять новый функционал и можно выводить его в продакшн хоть каждые пару дней; и видел микросервисные архитектуры, в которых добавление незначительной фичи — боль на пару месяцев. Не так важны пункты ниже, как первые три, которые большинство архитекторов/директоров/менеджеров/разработчиков обычно игнорируют. Потому что работать над этими тремя вещами сложно. Потому что проще каждый раз жить в контексте конкретной фичи, «как-то прикручивая ее сбоку», нежели работать в контексте всего продукта, да еще и держа в уме его будущее развитие. Потому что проще сфокусироваться на менее приоритетных целях, типа переезда на новую технологию разработки. И тому подобное…

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

Тема правильных имён настолько большая и больная, что я посвящу ей отдельный пост. Здесь же пока отмечу, что проблема выглядит совершенно по-разному для разработчиков и менеджеров с одной стороны и архитекторов — с другой. На горизонте менеджеров и разработчиков находятся обычно несколько приложений/сервисов. И кажется, почему бы не дать им имена героев любимого мультфильма? Это же остроумно. К тому же «характер» персонажа можно каким-нибудь хитрым образом ассоциировать с характером самой компоненты. А теперь представим архитектора или аналитика, на горизонте которых находятся пара сотен таких компонент. И вот он оказывается в зоопарке из мультяшных героев, персонажей кельтского эпоса, блюд итальянской кухни, астрономических объектов и пр. Эмоции в этом случае наиболее точно можно описать только матом. Однако врожденная скромность и модератор Хабра не позволят мне этого сделать. В общем, это непозитивные эмоции. Именование приложений/сервисов/систем должно быть обязанностью архитекторов и никого больше. Если в вашей компании это не так, постарайтесь это изменить

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

6. Детальная деплоймент-диаграмма. Обязательно должно быть показано какие компоненты в каких географиях должны быть развернуты, а также как они коммуницируют друг с другом, в каких аккаунтах живут, на какой инфрастуктуре исполняются и тому подобное

7. На интеграционных диаграммах должны быть показаны интеграции между всеми компонентами, задействованными в решении

8. Нарисуйте детальные flow-диаграммы для основных сценариев и для corner case-сценариев (то есть редких ситуаций, которые потребовали специальной проработки на этапе дизайна)

9. Если необходимо было выбирать какие-то сторонние технологии — например, базу данных — опишите, какие именно технологии были выбраны, какие кандидаты рассматривались и почему выбор был сделан так, как он был сделан

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

11. Разработайте стратегию постепенного разворачивания решения. (Gradual roll-out, то есть процедура, в результате которой решение разворачивается не одним махом на весь бизнес, а постепенно, чтобы снизить цену возможных ошибок). Стратегия gradual roll-out должна быть определена как для первичного релиза, так и для последующих изменений. Часто это два разных сценария, но еще чаще — вообще три: для первичного релиза, для последующих изменений, которые не нарушают контрактов с вышележащими компонентами, и для последующих изменений, которые нарушают контракты.
Не для всех типов продуктов gradual roll-out находится в ведении архитектора. Если компания контролирует инфраструктуру, на которой исполняются ее решения, то этот вопрос — прямая обязанность архитектора. Пример — интернет-сервисы. Если же контроля над инфрастуктурой у компании нет, то за gradual roll-out могут отвечать другие люди, например, специалисты по продажам — в простонародии «сэйлы». В компаниях, которые производят системы хранения данных (СХД), часто именно сэйлы находят «подходящих» клиентов, которые согласятся в обмен на какие-то плюшки испытать новую версию СХД на каких-нибудь некритичных нагрузках.
Gradual roll-out по первому сценарию — то есть без явного предупреждения клиентов и диалога с ними — вызывает во мне смешанные чувства. С одной стороны, конечно же, нужно снижать риски и для поставщика решения, и для его клиентов. Если в решении есть ошибки, которые не были отловлены на тестовой инфраструктуре, то пусть в продакшене от этого пострадает 1% клиентов, нежели все 100%. С другой стороны, gradual roll-out по первому сценарию в каком-то смысле не очень честный по отношению к клиентам. Интересно, что олдскульный мир, в котором софт распространялся на комакт-дисках, в плане gradual roll-out был честнее, чем современный. Потому что в те давние времена весь софт проходил через альфа- и бета-самцовтестеров и ранних адоптеров. И эти люди/бизнесы знали, на какие риски идут, и делали это добровольно. Сейчас же клиент интернет-сервисов может не знать, что на нём обкатывают новое решение. И конечно же, для обкатки обычно выбирают наименее «жирных» клиентов, чтобы, в случае провала, поставщик не сильно пострадал от их ухода. На «жирных» клиентов решение распространяют уже в последнюю очередь. В этом подходе компания-поставщик решения обычно оптимизирует свои собственные риски, а не риски клиентов. Дело в том, что «жирный» клиент с большой вероятностью переживёт нештатную ситуацию, а вот у мелкого бизнес может закрыться. Хотя здесь и не всё однозначно, потому что клиенты могут не быть конечными потребителями. И если это действительно так, то проблемы на стороне одного «жирного» клиента могут стать проблемами сотен его собственных клиентов — вплоть до их краха.
Итак, скрытый от клиентов gradual roll-out может приводить к интересным этическим дилеммам. Он не может быть на 100% честным, потому что честность — понятие относительное. То же самое относится к A/B тестированию на реальных клиентах. При таком тестировании компания обычно не предоставляет клиентам тот уровень сервиса, который на данный момент считает наилучшим. Но вместо этого она невидимо подкладывает некоторым своим клиентам (возможно, наименее жирным) альтернативный вариант услуг, который хочет сравнить по каким-то параметрам с основным вариантом. И это в корне отличается, например, от тестирования препаратов в медицине, где клиент добровольно подписывает согласие на участие в эксперименте

12. Стратегия отката решения на случай, если что-то пошло не так. Такая стратегия точно имеет смысл, если компания контролирует инфрастуктуру — физическую или виртуальную, — на которой работают ее решения. Но часто может иметь смысл и для других сценариев.
Раскатали вы, допустим, своё новое решение на 1% клиентов и вдруг обнаружили, что что-то идёт не так. Как будете возвращаться к старому варианту решения (если он был)? И как будете чинить то, что успели сломать? И как будете минимизировать ущерб для пострадавших клиентов? На все эти вопросы у архитектора должен быть хороший ответ. Причём заранее. До того, как начнётся пожар

13. Непрерывность бизнеса (business continuity). Отказоустойчивость, бэкапы, дублирование инфраструктуры, репликация, RPO, RTO, MTD — вот это вот всё

14. Убедитесь, что ваше решение на нарушает законодательства тех стран, в которых ваша компания ведёт бизнес. Например, китайские персональные данные не должны пересекать границу Китая. И даже если персональные данные не покидают пределов страны, при пересылке они должны быть зашифрованы.
Соблюдение стандартов, норм и законодательства — обычно не самая любимая тема технических специалистов. Потому что это не про технику. Но при этом учёт нормативных требований может существенно влиять на техническое решение, делая его обычно менее элегантным и более тяжеловесным

15. Чувствительная информация, которая сохраняется или передаётся в рамках вашего решения, не должна быть никому доступна внутри вашей компании, кроме тех, у кого есть легитимные основания для доступа к ней. Например, для устранения продакшн-инцидентов команде поддержки может понадобиться доступ к персональным данным. При этом будет здорово, если у них не будет возможности читать данные, не относящиеся к конкретному инциденту.
Заботясь о защите чувствительных данных, люди часто фокусируются на защите файлов и баз данных, но забывают про другие источники, например, логи. Хорошая практика — не создавать лишних копий чувствительных данных. В логах, на мой взгляд, чувствительным данным делать нечего.
Для некоторых типов данных текущий пункт является частью предыдущего. Это справедливо, например, для персональных данных. Законодательства большинства (всех?) стран запрещают использование персональных данных для «вторичных» целей. Например, нельзя использовать персональные данные для целей аналитики и «тюнинга» программных решений, если на это нет письменного разрешения от субъектов этих персональных данных

16. Убедитесь в защищенности вашего решения от внешних и внутренних атак. Обсудите решение с security-командой. Безопасность есть безопасность, здесь и добавить особо нечего. Единственное: старайтесь всегда использовать стандартные и проверенные решения от надежных поставщиков. Не пытайтесь ничего придумывать, если вы не супер-пупер эксперт в информационной безопасности или у вас в напарниках нет такого человека. Тем более, что еще не было ни одного супер-пупер решения по безопасности, которое не было бы взломано

17. Явным образом задокументируйте все неэффективности и технический долг, которые есть в вашем решении. Возьмите обязательство с себя и других ответственных устранить технический долг в ближайшем будущем. У этих обязательств должны быть четкие даты, и в пайплайне должны быть запланированы соответствующие проекты. Иначе технический долг останется с компанией навечно. Вообще технический долг — это то, что должно случаться в разработке достаточно редко. Если у вас каждый проект идет с техническим долгом, то у вас большие проблемы с разработкой. И я знаю одну такую компанию. Технический долг там никогда не устраняется и только копится. Много еще чего хочется написать на эту тему. И я даже чуть было не написал, но вовремя стёр. Оставим эту тему для отдельного поста

18. Проделайте анализ затрат на реализацию, внедрение, использование и поддержку решения. Посчитайте выгоду, которую оно принесет. (Расчет выгоды — обычно не задача архитектора, но исключения возможны. Например, если речь идет о технической оптимизации уже существующих решений). В расчетах необходимо учесть все географические регионы и все среды, в которых будет развернуто решение. Часто люди, делающие такой анализ, фокусируются только на продакшн-средах и совсем забывают про тестовые окружения. Однако иногда затраты на тестирование решения могут быть сопоставимы с затратами на его эксплуатацию в продакшене. Обычно такое случается, когда само решение или процесс его тестирования имеют изъяны.

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

19. SLA, или соглашение об уровне услуг. SLA должно быть определено как для всего решения, так и для каждого компонента, входящего в решение. Например, если решение — это новый интернет-сервис, то в SLA может входить верхняя граница времени отклика, количество запросов от одного клиента в секунду, доступность сервиса и т.п. В цифрах это может выглядеть примерно так: сервис достепен 99.99% времени круглогодично, независимо от времени суток и дня недели; если количество запросов от конкретного клиента не превышает 10 в секунду, то 95% запросов этого клиента будут выполнены в течение 0.4мс, а 5% могут выполняться дольше, однако не более, чем за 1с.

Все SLA должны быть обоснованы: почему они именно такие, а не другие? (При этом обоснование интегрального SLA всего решения — не задача архитектора, это бизнес-требование). Для каждого SLA должно быть понятно, как именно оно будет обеспечиваться технически

20. Обработка ошибок и таймаутов. Необходимо обсудить с командами разработчиков, как именно должны обрабатываться ошибки и таймауты. Нестандартные и неинтуитивные сценарии должны быть задокументированы

21. Логгирование и мониторинг. Что именно и куда логгируем. Какие метрики собираем и куда складируем. Какие параметры мониторим и как на них реагируем. Какие дэшборды настраиваем

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

Вот, пожалуй, и почти всё на сегодня. Остаётся добавить, что всё перечисленное выше (или то, что входит в понятие «архитектуры решения» именно в вашей компании) желательно отразить в шаблоне архитектурной документации. Чтобы каждый проект был задокументирован унифицированно, с указанием всей важной информации. И еще не помешает руководство по тому, как работать с шаблоном и как правильно прорабатывать наиболее сложные темы.

Теперь точно всё. Успешного нам всем архитекторства! Ведь все разработчики софта в каком-то смысле архитекторы.

Читайте так же: