Архитектура архитектуры: воспалённый аппендикс

Да, если запустить, то будет больно. Ну, а пока, возрадуемся же выигранному конкурсу! Ожидать горы золота или похвалы будет как минимум глупо. Солнце ещё высоко и время работать. Дядюшка Скрудж не выстроил бы своей империи, если б сразу бил по рукам и переходил к оплате. Поэтому его воплощение в вашем энтерпрайз-заказчике в очередной раз просто улыбнётся и опять поправит очки. Это, внучка, чтобы получше тебя видеть. И, конечно, чтоб читать текст приложений к контракту мелким шрифтом. Техническая часть всегда запрятана где-нибудь в Appendix 7/C.1.1

Copy of a written deal by Christoph Haizmann from 1669.Copy of a written deal by Christoph Haizmann from 1669.

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

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

Пятиминутка ненависти и личного опыта

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

·       Ищите самые большие классы

·       Места с максимальной цикломатической сложностью

·       Покрытие юнит тестами

·       Автоматические тесты интеграции

·       Ищите триггеры и процедуры в базе данных (особенно если это сиквел)

Вы скажете, а в чём секрет — это же стандартные метрики кода! А секрет в том, что почему-то никто их не смотрит! Даже хвалёные аудиторы. Иначе как можно купить IP на монолит без тестов с классами по 10000 строк, switch на 600 кейсов и половину бизнес логики в процедурах. Ненависть! Но стоит понимать, что частая ошибка покупающей стороны в том, что они думают, что покупают продукт. А такового никогда не было. Была команда. Как только эта команда покидает судно, оказывается, что они держали все доски голыми руками и без этих рук — это даже не лодка, а просто куски древесины в солёной, от слез покупателя, воде.

Функциональные требования

Начнём с очевидного, но невероятного. Помните на первых этапах подачу иконостаса с тех. стеком? Так вот время его перепроверить на соответствие всем изложенным в задании сценариям. И самое главное — передать ответственным игрокам с вашей стороны список жёстких конструкций. Таких жёстких, что легко ломают не только мозг при осмотре, но и спину при падении. У каждой технологии есть ограничения. Эти границы могут сильно влиять на бизнес. Для отдела продуктового дизайна и для вашего клиента подобные вещи совсем не очевидны. Даже если для вас это настолько тривиально, что и упоминания не стоит. Самым популярным кейсом будет не требование работы в оффлайн с полностью облачным бекэндом. Это на втором месте. На первом конечно же полная согласованность всех данных с постоянной доступностью в распределенной системе. На этом невысказанном предположении зачастую строится очень много критического функционала.  Сколько бы раз вы не повторяли мантру Брюера — все будут считать это какой-то теоретической лабудой. Мы то не в каменном веке, вот сейчас как сделаем… Даже эксперты, которых вам предлагают облачные платформы в 80% (5 из 6 на моём опыте) уверены, что если вы работаете по «well-architectured» шаблонам, то никаких проблем с согласованностью данных не будет. «Это проблемы конкурентов. В нашем облаке такого быть не может!».

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

Дедлайны при этом никто не двигает. Ко времени крупных конфликтов требований обе стороны уже где-нибудь накосячили и предпочитают не трогать status quo. Несмотря на то, что я упомянул выход в свет через год, релиз первой версии обычно намного раньше. Просто в начале он попадает на синтетические тесты в лаборатории (UAT, SIT, PPT). Там же первые интеграционные проблемы, не готовность инфраструктур клиента, баги у всех участников процесса и ещё куча приятных мелочей. Так что первые полгода всё копаются в сете известных требований, пытаясь наладить процессы и стабилизировать системы. На этом этапе сюрпризов практически не возникает. Сюрпризом будет, если всё заработает с первого раза.

К неизвестному функционалу могут добавиться регуляции. Если о трендах технологий стоит узнавать в новом свете, то законодательства и геополитику смотреть в старом. Смотрите на абстрактную Скандинавию, если в вашей системе есть финансовые или личные данные. Не обязательно следовать GDPR, если у вас внутренний рынок в Азии, но ваша архитектура не должна создавать помехи, если что-то подобное потребуют. Защита данных, цифровая фискализация, электронный документооборот и самообслуживание — расползаются по планете и сферам бизнеса. Просто заранее подумайте не только о разных хранилищах для разных данных, но и в случаях, где данные смешиваются — система должна позволять работать корректно, если позже часть исчезнет. Да, да, как клиент и просил — отказоустойчивость и микросервисы. А если в штатах введу оплату в магазинах в каких-нибудь токенах, то через год-джва ждите и у вас. Значит главное не делать аксиомы из единого языка, валюты, часового пояса, страны и наличия живого посредника. Коронавирус стал хорошим катализатором автоматизации процессов.

Нефункциональные требования

Тут то и игла в яйце Кащея. Есть два варианта: эта часть приложения будет очень короткой, либо безумно длинной. Конечно, задача свести всё к первому варианту, но прав то клиент, а у вас слово только во внутренних обсуждениях. Если в проектировании я говорил, что красная линия — это архитектура, то в контракте красные линии — это Соглашение об уровне услуг. Их пересекать нельзя. Совсем. Вот свежий пример шапки таблицы из подобного приложения к контракту:

Appendix HeaderAppendix Header

Табличка была на 50 строк — это нормальный вариант. С таким количеством можно разобраться. Первое, что необходимо — структурировать строки в иерархию. Ни разу не видел цифр, которые бы сложились в эту цепочку нормально. Как это примерно выглядит (примерно, потому что мои подписки о неразглашении никто не отменял):

Номер

Требование

Время

1

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

10 минут

2

Максимально допустимое время на синхронизацию клиента

5 минут

3

М.д.в. отклика облачного центра

2 минуты

4

М.д.в время загрузки страницы журнала

1 минута

5

Минимальное время хранения записи в журнале

5 лет

6

М.д.в аутентификации пользователя

1 минута

7

М.д.в авторизации пользователя

1 минута

8

М.д.в перезагрузки системы

3 минуты

9

М.д.в недоступности системы для операций (в месяц)

5 минут

10

М.д.в рассинхронизации данных между клиентом и облаком

5 минут

И всё в таком духе. Абстрактный сценарий и какой-то лимит времени. Тот, кто эти цифры даёт — ваш заказчик. Ему не нужно с этим разбираться. Он просто озвучивает желания. Желания всегда ведут к результату лестницей Пенроуза. Так что в начале нужно разобрать всё, ступенькой за ступенькой, и сложить всё в поленницу. А потом упорядочить и структурировать. Что значит структурирование? Построить цепочку зависимостей сценариев в последовательности исполнения. Рассмотрим наш теоретический пример. Сразу скажу, что работать лучше на листе или доске, так как в красивые деревья не вырастут. Будет сложная диаграмма или зацикленные графы.  Я вот подобрал удобные сценарии, но всё равно нарисовать в ворде получается, как-то не очень:

Scenario TreeScenario Tree

С подобной диаграммой работать легче, а самое главное — намного проще объяснить другим. Надо сразу вписывать недостающие шаги. Допустим процесс логина в таблице отсутствует, но его составляющие есть. Опять-таки, если вокруг вас все специалисты и у вас такой авторитет, что решения объяснять не надо, то можно и пропустить живопись. Вполне ведь себе реальная ситуация, что технический специалист со стороны исполнителя просто говорит: «тут вот будет 5 вместо 2» — и заказчик сразу соглашается. Тем же, кто работает в реальном мире, советую рисовать. А потом быстро подбивать время и анализировать:

  • Минута выделена на загрузку какой-то страницы журнала. А эта страница у нас в облаке. И вот первое противоречие. Серверу разрешено 2 минуты, а клиенту 1 минута. Значит у нас 2 варианта — вписать, что загрузка журнала будет без данных (только клиент и кэш), либо указать на зависимость того, что журнал не может загрузиться быстрее ответа сервера.

  • Авторизация и аутентификация по минуте. Значит логин в облако займет 2 минуты, только если оба действия будут в одном запросе. И да, если вам понятно, что 1+1 = 2 только в презентации, а на самом деле есть еще прослойки верификаций, сериализации и тому подобное, то контракту это безразлично. Поэтому либо явным образом указывайте логин в таблице со всеми поправками, либо мелкий текст «агрегация функций будет вносить дополнительную задержку в процесс».

  • В сложных процессах стоит сделать картинку для клиента, чтоб явно было видно — внешний таймер не может быть меньше суммы внутренних:

Downtime breakdownDowntime breakdown

Когда вы разложили все тайминги и внесли коррективы, то теперь вспоминаем эскиз архитектуры и проверяем его. Вот тут указанно 5 лет данных хранить — база подходит? Как повлияет такой объём данных на производительность? Что синхронизируется на клиента и при каком соединении клиента и канале сервера влезает в 5 минут? То есть в прошлом шаге мы как бы смотрели вертикально, а теперь проходим горизонтально, рассматривая сценарий, а не ветку. То, что указали в таблице требований, заказчику видится как критичная функциональность. Зачастую, это те участки, которые плохо работают у него сейчас — болевые точки. Часто повторяющиеся пункты в диаграмме — потенциальные места для масштабирования.

На каждую строку в таблице нужно расписать точный сценарий с минимальным шумом. Лучше всего оторванный от жизни (лабораторный) и с учётом погрешностей. Задача дать настолько подробное описание, чтоб две разные команды на разных тестовых стендах смогли повторить и получить одинаковые данные. Retestability. Берём логин как пример:

Сервис Login выполненный на системе в сети (указываете состояние и скорость сети до сервера), клиентское приложение на машине с рекомендованными параметрами или выше (расписываете железо, включая скорость дисков), с системой включающей только минимально необходимое (лист prerequisites) в оптимальной конфигурации (ссылка на ваши документы) и горячем состоянии (после рестарта станции сделано 3 логина и тестируется только 4-ый успешный, и не позже чем через 5 секунда с последнего), без взаимодействия со внешними системами (всякие sso, oauth провайдеры, active directory и тд), с уровнем логирования (какой-то минимум)  в 11 утра во вторник (это важно, если у вас сервер в облаке — у инфраструктуры есть нагрузка и без вас) без особых событий (чемпионаты, чёрные пятницы и эпидемии), при ручном замере от нажатия клавиши ввод (триггер начала процесса — старт таймера), до появления приветственной надписи «такая то» (конечная точка — стоп таймера) в процессе без ошибок (может случиться какой-нибудь переезд/перенаправление сервисов) займёт не больше 2 секунд в 99% случаев (нужен временной промежуток, допустим месяц) с поправкой 280 мс х 2 на человеческую реакцию. Скрипт для приведения баз данных в эталонное состояние прилагается (ведь важно сколько юзеров и какая сложность ролей и размер базы). Почему это важно я уже упоминал в прошлых статьях, но приведу еще пару примеров ниже.

Из опыта:

Первый логин в систему после ночи занимал в 3 раза больше времени, чем следовало. По данным заказчика, вместо прописанных 5 секунд было 17. Последующий логин, кстати, занимал всего 1.5 секунды. В нашей лаборатории на тестах было 9 секунд, но всё равно больше 5. Выяснилось, что клиент замерял время от провода смарт-карты в пинпаде, а мы вводили данные в форме приложения. Мелочь, но в переговорах сразу понизило пламя — 9 не 17. Начали разбирать процесс. Помимо того, что ночью антивирус забирал ресурсы и клиентская аппликация падала в пейдж, так еще и внешняя система распознавания карты работника требовала разрыва сессии, реинициализации соединения и оживала медленно. Антивируса быть не должно было, но у нас нигде не было указанно, что нельзя. То, что внешняя система нас тормозит, тоже никого не волновало. Ну и сама абсурдность кризиса, что только первый и единственный юзер в день ждёт лишние секунды — смущала только меня, но не адвокатов.  В контракте есть такая точка — старт обслуживания , после которой баги уже не «по гарантии», а за деньги (обычно подпиской). Эта точка приближалась, и заказчик решил продлить гарантию открыв спор по SLA. Учитывая, что разработка системы разогрева, перенос интеграции карт в отдельный модуль с отдельным прогревом заняли около месяца, 3 стадии тестирования с последующей публикацией в прод. еще 2 недели, а потом еще не один месяц на обновление всех клиентов (по контракту на новую версию за раз не могло перейти больше 10% локаций в неделю, чтоб снизить риск), то заказчик выиграл пол года.

Требования между строк

Важный момент — некоторые требования не указаны явно. Допустим в разделе про безопасность может стоять размытое «устойчивый алгоритм шифрования со сложным ключом» или еще хуже — стандарт сертификации, который включает в себя целый комплекс технологий. Так вот такая формулировка будет означать, что со временем алгоритм придётся менять. Технологии не стоят на месте и то, что было безопасно вчера уже доламывают сегодня. За лет 5 точно нужно будет сменить систему защиты и криптографии.

Загвоздка безопасности в том, что тут, зачастую, не может быть обратной совместимости. Подозрительные люди говорят вам, что у них есть копия ключа от вашего офиса. Вы же не вставите новый замок в соседнюю дверь, оставив в основной старый. Даже если будет куча тех, кому вы не смогли сразу выдать новый ключ. Так и тут. Если сломали щиты, то либо в проде появляются сразу две системы: новая и старая, и постепенно идёт миграция пользователей из уязвимой в защищенную версию. Либо мы всё ломаем и есть только новая версия и те, кого мы не обслуживаем до обновления. И тут вы опять упрётесь рогами в те же ворота SLA о доступности системы.

Эхо из прошлого.

Клиентская часть системы жутко тормозила на первых версиях 7-ой винды на машинах с 1 Gb RAM. Когда подписывался контракт в ходу была ХР. В Энтерпрайз не заходят все версии, особенно если есть специфические драйвера и сборки. А потом SSL скомпрометировали, а более защищённая версия TLS уже не имела поддержки в старой оси. Никаким бубнами заставить работать плавно и хорошо не удалось. Штраф был в пол суммы контракта. Так что, потеряв месяц+ на оптимизации пришлось обращаться к компании, которая обслуживала железо этого клиента (всё та же боязнь vendor lock) и оплатить покупку двух линеек по два гига на 10 тысяч машин по всей стране с установкой (техник на выезде в каждую точку). В данном случае никаких хитростей со стороны заказчика не было — переход на другую операционку был вынужденный (требование сектора), а наша система действительно была нежизнеспособна в этих условиях.

Кстати, о доступности. Вы ведь понимаете, что доступность для пользователя системы с облачным сервисом будет равна устойчивости машины, соединения, электроснабжения и только потом эти хвалёные 99.99999. Заказчика мало волнует то, что где-то в облаке всё работает, если конкретный человек в конкретном офисе не сможет этим воспользоваться. Так что объясните это хорошо своим коллегам (на пальцах, как у якудза), которые будут подписывать. Самые простые для понимания примеры в комбинаторике — монетки и кубики: «У нас есть несколько кубиков, каждый на 365 граней и представляют собой доступность или надежность инфраструктуры в годовом масштабе.» Подставляем данные, я люблю использовать полу-реальные данные со своего лаптопа на примере доступа к электронной почте — некий облачный жи-mail. Открываете логи раутера, журнал оси и показываете пару записей о перезагрузке или разрыве соединения, а потом экстраполируете на месяц и год. Допустим за последний год у нас не было электричества 17 часов, лаптоп был в ремонте 30 часов, проблемы с соединением 4 минуты в сутки, а это 24 часа в год. И последний кубик — недоступность самого облака, которая будет не больше часа в год. Так как любая из этих проблем означает отсутствие доступа к мейлам, то шанс проверить жи-почту в прошлом году был:

availability-probabilityavailability-probability

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

Ещё разок вернёмся к пункту 10 в таблице требований. Что конкретно он означает: интервал синхронизации или временной лимит работы в оффлайн? Двусмысленность в контракте лучше не допускать. Если вам повезло, и компания аудитор выступает арбитром во время всего периода развёртывания, то это уменьшит риск разночтений. Аудиторы страшный враг вашей компании и ваш хороший друг. Они будут мешать эффективным менеджерам игнорировать заявленные процедуры и не применять продемонстрированные процессы, но зато смогут помочь объяснить клиенту сложность некоторых требований и прийти к компромиссам.

© Habrahabr.ru