Архитектура архитектуры. Шаг 5: один за всех и все на одного

    Продолжение. К предыдущим постам и карте цикла.

    В жизни каждого проекта наступает тот самый волнительный и незабываемый момент, когда от архитектора требуется только архитектура. Волнительный он по вполне понятным причинам. К этому моменту вы уже столько раз повторяли и уточняли дизайн, что и сами стали верить в эту сказку. А теперь вот раз и надо архитектуру. Не концепции и технологии, а вот прям весь хребет слона, которого будут растить пару лет в инкубаторе, а потом лет 10 на пастбищах по всему миру, пока из резервации он не попадёт в консервацию. Ну а памятным это событие делает тот факт, что все последующие годы вам будут припоминать всё мелкие недочёты, которые почему-то вы не смогли предвидеть. Ведь вам дали неделю, а может даже и целых две на то, чтоб определить направление и основные вехи разработки всех команд на годы вперёд.

    Unus pro omnibus, omnes pro uno
    Unus pro omnibus, omnes pro uno

    Итак, контракт подписан и вашей компании выслали официальное извещение о победе на тендере. Теперь пора переходить от теории к практике. Вы работаете в современной компании и все отделы и департаменты давно работают по Agile. То есть их горизонт знаний о проекте ограничен несколькими итерациями. Ну вот эта вот любимая всеми картинка:

    Agile development concept
    Agile development concept

    Если бы архитектору дома сказали, что клиенту хватит палатки или может в крайнем случае бытовки, а через год попросили добавить 3 этажа, то он бы, наверное, удивился. Еще сильней он бы удивился, когда еще через год ему добавили требование лифта, еще 5-ти этажей и бассейна на крыше. А чтобы он думал и делал, когда за пару месяцев до сдачи проекта ему сказали, что там еще подземная парковка на 100 машин должна быть – я уж и не знаю. А вот в программной разработке – это всё обычное дело. У нас ведь все такие гибкие и топят за адаптивность, а не выстрелы на опережение (особенно если они уже дорогие, но еще не обоснованные). И если вы просто будете апеллировать к методологии, которая подразумевает не только инкрементальность разработки, но и постоянное корректирование уже созданного, то ваша карьера будет яркой, но не долгой.

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

    Architecture on feature map
    Architecture on feature map

    Возвращаясь к первой статье цикла, ещё раз озвучу своё мнение о назначении архитектуры. Это оптимальный путь решения задач бизнеса. При выборе паттернов проектирования, методологии работы, технологий и фреймворков, мы всегда получаем набор функций и решений, которые работают из коробки и набор ограничений из табакерки. Ещё до финальной подписи в контракте на души разработчиков, вы должны были перепроверить всё, что заявлено. Значит основная парадигма у нас есть. Что-то типа: микросервисы в облаке с разбивкой по DDD с локальным клиентом на Java. Полезность правила измеряется количеством исключений. Так что чем меньше перекосов в сторону монолита на клиенте или костылей вокруг облака – тем лучше. Тут никакого откровения нет. Но, всё же не хочется быть автором ещё одной пустой статьи из серии «мы в компании Х решили всё сделать по У и у нас всё получилось». Ведь я-то как раз и хотел в статьях показать путь, которым приходят к выбору У и как даётся тот самый success story.

    Как вы, возможно, читали ранее – выбор часто делают за вас. Технологии - из того, что знает команда, методология тоже какая уж есть в вашей корпорации, провайдеры и стандарты обычно определяются заказчиком как одно из требований тендера. Вам же достаётся игра в Counter Strike. Пытаетесь обезвредить бомбы, которые уже заложены. Особенности работы с большими предприятиями я уже описывал. Так что сам по себе пазл не сложится. Облако и микросервисы – стандарт де-факто и, почти наверняка, вас не миновала чаша сия. Такие системы всегда обладают атрибутами AP. Значит стоит определить какие узлы требуют CA.

    Энтерпрайз системы в основном рассчитаны на использование сотрудниками компании для автоматизации процессов. Зачастую процессы критические и производственные. Значит нужно чётко понимать, что должно работать вне облака. Почтовое отделение, заводик или магазин должны продолжать обслуживать даже, когда облако не доступно (это не облако упало, а ваш клиент потерял соединение). И данные на месте нужны актуальные (тот самый СА вариант). Если мы возьмём за пример систему управления логистикой, где у нас есть куча грузовиков развозящих товары по дорогам страны, то понятно, что никакие изменения данных в облачном диспетчере не изменят содержимое кузова. Ну и совсем не хочется, чтоб этот грузовик простаивал, если у него нет связи с сетью. Значит его локальная система должна иметь возможность учёта товара, просмотра маршрута и управления исключениями, без которых в реальной жизни никак. Глаз в облаке будет довольствоваться данными последней синхронизации и предполагаемым прогрессом (эвристикой текущего состояния). Заявленные микросервисы на планшет водителя устанавливать видимо тоже не стоит. Они уместны в центре управления, высоко в облаках, там, где вершина корпоративной пирамиды. Но процессы и данные у центра и аппликации водителя будут перекликаться процентов на 70. Это как раз и создаёт предпосылки к путаницам с распределёнными и модульными монолитами. Нежелание повторяться приводит к сильно связанным громоздким сервисам и полурабочему зоопарку клиентов.

    Иногда всё же стоит дублировать логику и учесть, что она может отличаться (центральная система должна уметь обрабатывать данные с оффлайновых приложений, даже если они не соответствуют её ожиданиям). Центр знает, что в машине 3 ящика молока и в каждом пункте доставки должны выгрузить один – в конечной синхронизации может оказаться, что 3 места посетили, а доставили только 2 ящика. Водитель забыл. Или разбил. Или на одной из точек выгрузил 2. Если вы всё время в онлайне, то постоянный поток данных позволяет следить и корректировать поведение. Допустим через нотификации и подтверждениях о выгрузки товара со стороны получателя. Без этого – физический мир просто сообщает вам фактическое состояние и живите с этим как хотите.

    Если вам повезло и логику можно инкапсулировать в модуль, который легко впишется и в сервис, и в аппликацию на планшете (reuse over duplication), то данные всё равно будут жить своей жизнью. Но чем меньше кода, тем лучше. Так что если у вас предполагается работа без доступности центра, то стоит свести внесетевые функции к минимуму. Стандартная отказоустойчивость как часть дизайна. Водитель должен отчитаться о разбитом ящике молока – не стоит сразу дублировать форму на случай, если связи нет. Может достаточно создать напоминание об этом событии с принудительным заполнением в конце маршрута и оставить сам рапорт только сервисом на бэке? Не работает встроенный принтер – сохраним файл. А иногда и просто добавим бумажный формуляр к планшету, а в аппликации потребуем сделать его снимок.

    Ошибки молодости

    Разработчик сфокусирован на задании и не знает всей предыстории и, главное, последующих приключениях того, что он пишет. Особенно в большом проекте, где он один из легиона. Чтобы попасть в production и выстрелить, ошибка имплементации должна пережить всякие ревью, рефакториниги, автоматическое и ручное тестирование. Да и после этого, обычно, починить можно максимум за недельку. Редко, когда на ошибочном исполнении висят несколько процессов (хотя и такое бывает). А вот недочёт проектирования может вылиться в месяцы работы.  Одним из таких подводных камней была моя уверенность, что новая система сменит старую и автоматизация заменит ручной труд. Система датчиков должна была свести к минимуму интеракцию с пользователем, искоренить человеческий фактор и поднять достоверность данных. На деле же заказчик боялся довериться системе и не стал менять процедуры ручных проверок. Ни в каких требованиях и ожиданиях это не было обговорено. Ручной ввод был на случай отказа датчиков, а не в дополнение к ним. Система не могла справиться с прыжками и конфликтами в показаниях между данными от ручных измерений и сенсорами. Пришлось добавить еще один сервис для коррекции входных данных, перенаправить потоки, поменять процессы и переустановить весь прод. С тех пор я всегда рассчитываю на то, что новый продукт работает side-by-side. Этот подход так же помогает подготовиться к миграции и поддержке множества версий.

    Ну и как найти и учесть все подобные случаи заранее? А никак. Архитектура большого проекта похожа на школьные опыты по биологии. Там, где рассматривают кожицу лука под микроскопом. Сначала вы смотрите на всё со стороны и добавляете контрастную жидкость. Потом вставляете в микроскоп и настраиваете свет, пытаясь остаться в границах на минимальном приближении. И лишь найдя цель, меняете увеличение на максимум фокусируетесь на деталях. То есть сначала вы делали блок схему, а потом перед непосредственной разработкой будете делать архитектуру каждого блока, заполняя его деталями. По необходимости будете добавлять всякие flow и sequence – они легче всего воспринимаются всеми участниками процесса разработки. Так что в отличии от строительства, вы начинаете разработку с наброска, а детальную архитектуру получите лишь в конце. Поэтому так полезны, хоть и не популярны, большие UML пакеты, позволяющие ссылки на диаграммы и вложенные чарты. Разработка – это drill down от blue-print до detailed architecture.

    Agile architecture concept
    Agile architecture concept

    Что же нужно делать в начале – это инфраструктуру. То, что заказчик явным образом не просит, а значит и добавить её позже будет сложно. Если и не технически, то политически точно. Основа любого проекта – команда. Именно на людях стоит сосредоточится и задать единый язык и шаблон. По законам Мёрфи – если в коде будет плохой кусок, то его обязательно выберут как пример и размножат бесчисленное количество раз. Обговорите с разработчиками структуру проекта, названия и, если нужно, стилистику кода. Многие считают нейминг не важным, но в долгой разработке у всего есть дополнительный вес. Единый язык продуктового отдела и разработчиков, увековеченный в коде, сильно упрощает поддержку и модификации. Представьте, что вам на рабочий стол попал проект в пару сотен тысяч строк, десятки сервисов и баг, который говорит, что расчёт потенциала не верен. Если поиск в базе кода и системе планирования/отслеживания задач с ключевым словом «потенциал» ничего не даст, то вас ждут долгие часы выяснения правильного сценария и пошаговой отладки бизнес-процесса, разбросанного по куче модулей. Вам кажется, что пример высосан из пальца, но мне не раз доводилось самому копаться в подобном, пахнущем кислой радугой, проекте. Обилие синонимов, всяких акронимов и аббревиатур сделает вашу жизнь еще сложнее.

    Всё, что нужно делать вручную, будут игнорировать так или иначе. Начало проекта – начало автоматизации. Тут и юнит тесты (для правильного дизайна и возможности рефакторинга), и интеграционные тесты (для стабильности проекта и уменьшения time-to-market), и метрики кода (всевозможные KPI) – всё часть CI-CD. Игры в микросервисы с ручной настройкой и развёрткой оставим мазохистам. Нам необходима команда DevOps. Формально или нет, но кто-то должен быть ответственным за правильную конфигурацию и установку среды. Среды разработки, среды проверок, среды интеграции и т.д. Иначе в будущем вместо среды вас будут ждать суббота и воскресенье разработки и проверки. В производственных системах редко можно найти изолированные бизнес-кейсы.  Все микросервисы должны будут взаимодействовать друг с другом и между ними будет явная или не явная зависимость. Устранить этот недостаток можно еще одним уровнем абстракции! Cервис – оркестратор сервисов. Тот, что вызывает цепочку других сервисов, чтоб обеспечить необходимый результат.  

    Delivery service orchestrates domain services in business flow
    Delivery service orchestrates domain services in business flow

    Вернёмся к нашему грузовику. Водитель хочет начать маршрут. Для этого необходимо: получить квоту на топливо, заправиться, погрузить товар, подтвердить погрузку, составить маршрут, сообщить на точки отгрузки предположительное время прибытия и так далее. Если каждый этап станет отдельным сервисом, то клиент будет отвечать за бизнес. А хотелось бы чтоб он был как можно тоньше. Удобно группировать несколько таких шагов в один процесс и вызов. Сервис заправки – он проверит маршрут, квоту и авторизирует заправку. То есть последовательно запустит 3–4  микросервиса (с десяток API вызовов и сохранить состояние между ними). Конечный автомат. Плодить такие сервисы бесплатно тоже нельзя. Стоит создать жирненькие мета-сервисы объединяющие кросс-домейн процессы, вместо того, чтоб рулить всем из фронта. Не легковесные они, потому как знают многое о многих и строят сложные процессы взаимодействия. Однако связь односторонняя. Собственно – это простой медиатор. Основная причина не раздувать клиентскую часть лежит в разнообразии таких приложений с однообразием и стандартизацией процесса. Абсолютно тот же функционал должен быть доступен в каком-нибудь легаси винформ монолите, нативном андройд клиенте, который кто-то запилил вашему заказчику пару лет назад и новой веб-аппликации из вашего пакета. Очень удобно все три приложения заставить обращаться к одному сервису, сделав миграцию из legacy в nextgen быстрой и легко управляемой.

    Помимо планирования есть еще и проверки того, что план соблюдают. Настройка правил статистического анализатора кода и внедрение проектных тестов (solution unit-test), на мой взгляд, задача архитектора. Что такое проектные тесты? Это жесткие правила ломающие билд при нарушении, написанные в виде юнит теста или плагина к какому-нибудь сонару. Примеры подобных тестов:

    • Минимальное покрытие тестами в определённых модулях

    • Ограничение по количеству заигнориных тестов

    • Тест на то, что тест с ограничением тестов в игноре не заигнорин

    • Список запрещённых референсов (например уровень бизнес-логики не должен знать о типах в базе данных)

    • Список разрешённых референсов (допустим open source и legacy библиотеки)

    • Разрешённые типы файлов (к примеру файлов .sql не должно существовать)

    • Naming и структура проекта (если должно быть 3 слоя и каждый отдельной библиотекой, а тесты заканчиваться на _Test то будьте любезны)

    • Парсинг и проверка скриптов на соответствие (например скрипт конфигурации должен создавать одноименную запись и в параметрах окружения и в файлах)

    • Минимальное количество строк лога в каждом классе (если актуально)

    • Типы исключений и их иерархия (допустим модуль безопасности не должен отдавать детальные exception, так что там может быть только один тип и без текста)

    Такие тесты всегда делаются под конкретный проект и архитектуру решения. Всё это заставляет разработчика задуматься еще раз, и не даёт его менеджерам возможность легко увеличить тех.долг. Только не надо делать из тестов фетиш. Типа: «Каждый модуль должен быть на 100% покрыт тестами.». 100% покрытие тестом необходимое условие для пельменей, а не для проекта.

    Теперь пора строить план. Что вы должны выдать в качестве необходимого функционала – вам сообщат все заинтересованные участники. Надо понять как много (или мало) останется на инфраструктуру. Все Agile, но только, когда им удобно. Выделить месяц на создание основы проекта без деловой логики/функционала, почему-то не хотят. Не достаточно прозрачно. Или сложно тестировать. Все уверены, что основа проекта закладывается с самой сложной формы в UI. Вот gateway ваш, безопасность и мониторинг можно и позже – их же всё равно никто не видит. А заказчику нужно что-то показать. Так что опять нужно будет продавать необходимость и своевременность. Как обычно апеллируя к тому, что увеличение числа процессов и компонентов прямо пропорционально стоимости внедрения 3-х «С» - сквозных системных служб. И, как всегда, создаётся впечатление, что это понимаете вы и пара инженеров, но не управленцы.

    Если всё получилось, то «земля, прощай» и в добрый путь.


    Similar posts

    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 4

      +1
      С одной стороны — отличная статья, и не менее отличные выпады в сторону бездумного применения новомодных веяний, с которыми я полностью согласен, а на кое-что посмотрел с новой точки зрения. С другой постоянно что-то смущает в этом цикле, и эта статья помогла понять. Смущает категоричность утверждений и распространение “опыта выжившего” в конкретных ситуациях на все и любые проекты. Возможно я не прав и таких мыслей не было, но тон и лексика звучат именно так.

      Реальность все-таки куда шире, от проектов попадающих под действительно жесткий regulatory compliance, до проектов в которых важнее всего доказать жизнеспособность идеи. И от разовых проектов на три месяца, когда с заказчиком больше никогда не увидишься — до проектов в которых с заказчиком надо жить по 20 лет потом. И на одном краю всего спектра все описанное будет выглядеть недостаточным “детским садом” и “деревенской самодеятельностью”, а на другом превратиться в неподъемное бюрократическое бремя и скорее убьет потенциально успешный проект. Мне в этом плане “не повезло”, я работаю не в нише, как консультант я сталкиваюсь с самыми разными проектами — от системы безопасности АЭС до стартапа пытающегося вытащить совершенно безумную на первый взгляд идею.

      Ну и да, не всегда и не везде sales и executives настолько не способны или найти заказчика понимающего как на самом деле делаются проекты или объяснить ему как это делается. Поэтому нахождение с состоянии “никто кроме меня этого не понимает” — совершенно не обязательное. Опять-таки когда меня просят посмотреть процессы — такие моменты это первый “красный флаг” того, что что-то идет сильно не так. Вон в ПыМыБОК аж специально дисциплины под это специально ввели — управление коммуникациями и управление ожиданиями. Мне конечно проще, я в позиции когда я могу на это напрямую влиять, но таки иногда и от Agile есть польза в таких случаях. Когда мы начинаем задавать себе честные вопросы “на фига мы делаем работу которая на самом деле не приносит пользы” — очень быстро выясняется что или мы, или те самые злобные другие действуем не по злому умыслу, а просто из-за недостатка прозрачности.

      Не лезу с советами, но мне просто кажется две маленьких вещи:
      — Четкое определение круга проектов и ситуаций к которым относятся все утверждения
      — И оценка “по чем нам это обошлось” не только для критикуемых решений, но и для своих (потому что бесплатного сыра не бывает, мы всегда чем-то жертвуем, и часто самый интересный анализ лежит не в плоскости “что мы получили”, а в плоскости “чем мы за это заплатили/что мы потеряли”)
      сделают просто хороший цикл статей — вот прям таким, что хоть в учебник вставляй. Мне почему-то кажется что он того стоит.
        +1

        Спасибо за развёрнутый коментарий!
        Весь цикл (если он когда-нибудь будет) описывает процесс, а не результат. Я делюсь своим опытом (шаг2: продуктовая корпорация с энтерпрайз заказами, долгий срок разработки и обслуживания) большее по стадиям развития решения — они на 80% стандартные в энерпрайз. Сама же архитектура и реализация уже сильно относятся к конкретной задаче и серебряных пуль нет. Категорично писать — "делайте серверлесс на graphQL", на мой взгляд, признак непрофессионализма. А вот "подумайте нужно ли вам облако" — подход верный во всех случаях. Как вы сами и отметили — за всё нужно платить.
        В плане не всегда архитектор единственный специалист, конечно, вы правы. Но принцип Питера приводит любые корпорации к состоянию, что те, кто понимают, не влияют на процесс — не принимают решения. АЭС прислушивается к вашим словам, потому что они уже прошли весь путь внутреннего пищеварения, раз обратились к стороннему консультанту.


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

          +1
          Вам спасибо за статьи! Жду завершения цикла, сразу же добавлю своим в обязательное чтение для развития кругозора.

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

          p.p.s. Комментариев и лайков, кстати, почти нет. Верный признак дельной статьи. :-)
            0

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

      Only users with full accounts can post comments. Log in, please.