Продолжение. К предыдущим постам и карте цикла.
Хотели когда-нибудь примерить на себя костюмчик успешного архитектора из мира больших бизнесов? Ну тех, кто зарабатывает на лекциях и подкастах больше, чем на основной работе. Рецепт то не особенно сложный: пара успешных проектов и кул стори в интернетах. Впахивай и впаривай! Иногда в комплекте к костюму идут одноцветные тапочки…
![Успешный Арни с цитатой успешного Теда Тёрнера Успешный Арни с цитатой успешного Теда Тёрнера](https://habrastorage.org/getpro/habr/upload_files/bb6/25d/5d9/bb625d5d96469756a8405b30b3742701.jpg)
Успешный успех. Звучит как сказка! Вот только если вы прагматичный (душный и токсичный) архитектор, то carpe diem на фоне memento mori. Те, кто поднимают золотое знамя успеха, любят поднимать на вилы тех, кто осторожно предлагает подождать с конфети и фейерверками. Просто в свете и шуме салютов можно не услышать криков и пропустить тревожные сигнальные ракеты. Ведь об успехе заявляют не по окончании проекта. А зачастую даже не в точке первой прибыльности. Закончили развёртку и всё – успех! Вроде бы и обязательства выполнены, но, кажется, что-то забыли... Если софтина работает, то вы не поверите, с ней начинают работать! И как бы ни хотелось разработчикам, создание – относительно короткий срок в сравнении с использованием. Ход мысли довольно прост, но почему-то всегда встает на пол пути:
![Где там должен быть профит. Где там должен быть профит.](https://habrastorage.org/getpro/habr/upload_files/e50/ad6/ef4/e50ad6ef436dd343a06ab8a482cecb7d.jpg)
Во время планирования и разработки системы вы воевали с адептами карго культа. Они верят в звучные имена технологий и призывают их во имя победы. Достаточно чтоб у нас было "Облако" или "Микросервисы" и охота будет удачной, а племя сытым. Вот охота на территориях клиента принесла первого буйвола. Теперь шаманов-культистов сменят каннибалы. У успеха много отцов и всех не прокормить с одной тушки. Вдруг окажется, что штат слишком раздут. Но проект же успешен и должен расти. Было 4 команды по 5 человек - станет 6 команд по 3.
Энтерпрайз - всё же продуктовая история. Только очень богатые среди больших и богатых (ну или с особыми необходимостями, как сейчас правильно говорить) делают разработку системы только для себя и под себя (что-то типа гибридного аутсорса). Остальные адаптируют платформы (продукты одних корпораций для других корпораций).
На этапе эксплуатации системы основной задачей архитектора станет уменьшение страданий. В первую очередь самого архитектора. При разработке платформы ваша компания скорее всего продавала идеи и презентации. Продукта еще не было. Это понимают и клиенты. Так что первые заказы – наверняка в убыток. И как только уже оплаченные требования заканчиваются, начинает пахнуть деньгами. У компании с новым продуктом лишь одна задача – отбить деньги с разработки платформы. Для этого обычно требуют две вещи: история успеха (успешный клиент поможет продвинуть новый продукт на рынке) и сокращение расходов. Когда продукт вышел в свет, разработка не прекращается. Есть изменения стандартов, законов и рынка. Новые требования будут поступать постоянно. CR – SOW/BOM – CD – CI – CD. К чести компаний, я не видел случаев, когда клиента просто начинают доить, завышая цену за CR. Есть какой-то минимум маржи, который спускают сверху вниз, но и всё. Никаких в «в два-три раза», как обычно думают заказчики.
Вот, собственно, и весь секрет профессии. Архитектура, как и сам архитектор, нужны чтоб сэкономить деньги. Очень классно, когда можно избежать ошибок и трат на первых этапах – во время разработки. Но это лишь годика два из всего жизненного цикла. А вот уменьшать затраты на протяжении десятка летка лет – это мечта, обеспечивающая нам стабильность трудоустройства. И если в первые и критичные этапы вам приходилось спорить с продуктовыми менеджерами, начальниками разработки и кучей директоров ради сокращения времени и усилий, то теперь война будет за увеличение прибыли. Я говорил, что клиентов не дурят? Ну там сложная история. Знаете, как бывает – левая рука не ведает, что делает правая. В начале всё идет как по книге: получают запрос на изменение, продакт и архитектор дают первичный дизайн, отдел разработки дает начальную оценку и на этом основании выставляют счёт клиенту (с учётом рисков). Но как только всё подписали, появляются управленцы оптимизирующие расходы и сокращающие пути. Они пытаются «улучшить» решение и увеличить маржу.
Самая полезная штука этого этапа – документация прошлых шагов. Схемы, диаграммы и записи, сделанные во время разработки. В начале разработки вам дали картинку (видение продукта), потом порезали на пазл (все эти эпики и стори), и вы все вместе собрали этот пазл и передали заказчику. Теперь же необходимо будет постоянно дополнять эту головоломку новыми кусочками. Держать всю картину в голове, конечно, круто, но не практично. Так иметь перед глазами карту, пусть и не детальную – сильно упростит вам повседневную работу. В идеале вы даете форму кусочка и палитру, продакт готовит рисунок, а дальше уже девелопер сам. Но если у вас есть хорошо документированный кусок архитектуры, то вашу работу можно делегировать сразу разработчику, оставив на архитектора лишь ревью.
Идея делегировать решение вам может показаться странной, так как вам всё равно его нужно будет утвердить. Значит ответственность остаётся на ваших плечах. Как будто пашите вы, а зарплату тратит кто-то другая…. Однако на самом деле всё просто – у вас будет мало времени. Код велик как баобаб. И баобаб будет только расти. До начала эксплуатации у вас был один бэклог, хоть там и были периодические изменения и версионность. Теперь же у вас их стало как минимум два. Один, как и прежде – проектальный. Та часть, которая принадлежит клиенту и обслуживает конкретно его нужды и оборудование. Второй – продуктовый. Та часть, которая служит (или будет) платформой для других клиентов. Ванилька. И новые блоки будут достраиваться в оба потока параллельно с частичной миграцией и вымиранием/замещением между ними. И если ваша компания амбициозна, а клиенты крупные (сеть предприятий), то велик шанс, что потоков намного больше. В глобальном мире у вас будет слоёв 6–7, что обычно выливается в 4 и больше независимых стрима (инфра, глобальный бизнес, локальный бизнес, кастомизация клиента).
Инсайд двух крупных продуктовых корпораций:
Компания А изначально планировала разработку платформы отдельно, а кастомизации отдельно. Год занимались только бекэндом своего будущего продукта, чётко имплементируя все внешние связи и интерфейсы. В это время начали продажи и нашли трёх крупных клиентов. На второй год, уже основываясь на программных контрактах, началась разработка и кастомизаций. Получилось 4 разные команды, 3 из которых основываются на результатах четвёртой. Сырой продукт требовал доработок и рефакторинга, что в свою очередь приводило к изменениям и во всех трёх проектах. Позже выяснилось, что не учли геополитику и одна из трёх команд требовала всё больше правок в платформе и более сложных адаптаций. Платформу «временно» разделили на две. Временность продлилась 4 года. Всё это сказалось на сроках и вместо планированных 3-х лет на всё, получилось почти в два раза больше.
Компания Б получила заказ на разработку с большущим списком требований и малым бюджетом. Компромиссом стало соглашение с клиентом, что большую часть кода можно продавать другим. Так что менеджмент решил, что такое партнёрство даст шанс выйти из ниши производителя оборудования и стать полусофтверной продуктовой компанией. План был пилить год под того самого заказчика, а потом отрефакторить всё это дело и зажить на широкую ногу. Вот всё так и сделали – завернули 90% проекта в красивую обертку и назвали продуктом. Оказалось, что вот этот продукт в таком виде никому не нужен. И каждый потенциальный клиент хочет изменить как минимум половину, а потом еще и добавить свой бизнес. Первая же попытка продать другому клиенту привела к провалу с расходом на год разработки и выплатой неустоек. Понадобилось еще пару лет для перезапуска.
![Слои бэклога глобального on-prem продукта Слои бэклога глобального on-prem продукта](https://habrastorage.org/getpro/habr/upload_files/4d7/02b/684/4d702b684481efd0b25311dfc4e25b16.jpg)
В основе лежат базовые вещи типа логирования, метрик, безопасности, протоколы и всё такое. Следующим слоем ляжет основной дистиллят бизнес-логики (допустим у нас банк). Над ним глобальные вещи, общие для многих территорий, как например язык, системы мер и тому подобное (григорианский календарь, метры, английский, глобальные стандарты). Дальше будет слой местных особенностей, таких как законы (валюта, налоги, местные регуляции). Последние слои уже не платформа, а клиентский проект – кастомизация под основной бизнес, а за ним возможно франшизы и побочные бизнесы. Слоёв может быть больше и разделение немного другим. Допустим в Европе есть общие законы для всего ЕС, но языки разные. Валюта тоже не ложится один к одному, да еще и законы в каждой стране свои. У клиента может быть несколько подвидов бизнеса и разного рода партнеры/дилеры. А так как клиентов у вас несколько, то уровень абстракции платформы должен удовлетворять потребности каждого из них.
Почему нас это волнует только сейчас, а не на этапе первичного проектирования? Строить изначально глобальный продукт очень дорого. Исходя из опыта – года 2-3 чистых убытков на создание платформы и лишь потом первые клиенты. Так как любой клиент будет требовать доработку, интеграции и адаптацию, а потом и поддержку, то лишь часть денег пойдёт в счёт покрытия расходов самой платформы. Которую, кстати, надо будет тоже развивать, чтоб соответствовать меняющемуся рынку. Поэтому менеджмент смотрит в цифры и планирует всего на пару лет вперёд. Ну а архитектор? Архитектор работает с требованиями, а как вы догадались никаких далеко идущих требований ни клиент, ни продуктовый отдел попросту не предъявляли. И если сам архитектор не специалист в предметной области и не имеет подходящего опыта и рефернсов – мы имеем того, ну в общем… Вот и большой сюрприз – после того как вы потратили годы на проектирование и разработку, надо переделывать, перестраивать и ломать.
Без спайса гильдия архитекторов не может указать, какие вещи в бизнес-процессах клиента будут меняться, а какие нет. Так что соломки на всё не напасёшься, а куда стелить не ясно. К чему можно и нужно готовиться – к интеграции. Со временем количество внешних сервисов и устройств только растёт. То, что ещё вчера делали вручную – будут делать машины под управлением контроллеров. Ну и постоянно растёт количество датчиков и всяких IOT. Которые даже не связанны с производством/делом. Допустим подключение дверей к умным магнитным замкам или камера распознавания номеров машин, недавно появившаяся на парковке завода. Кому-нибудь точно придёт в голову идея «вот тут потрекать, тут связать данные и вот в такой отчётик». Если у вас есть четкая картина API, то разработчики и сами справятся. Только надо проследить, чтоб решение этой задачи не закрыло будущее для смежных заданий. Не всегда разработчику известно, где и как еще используются необходимые ему сервисы.
Широкий взгляд и опыт
Одну легаси систему целиком запихали в образ и повесили в облако. Вполне обычная потребность - знать сколько копий в работе и распределять запросы, требовала сервис для проверки состояния. Документация была и найдена команда вполне квалифицированных людей для этой задачи. Все решили за пол спринта и отправили в прод. Через месяц вдруг заметили, что места система стала жрать немерено. Начали рыть, что изменилось и пришли к этому самому сервису работоспособности. Система была монолитом и возможностей что-то вызвать было не много. Программист решил просто делать логин и проверять ответ. А вот чего он не знал, так что для этой системы сам логин – критичное действие. И это действие требовало занесения в несколько журналов и запускало всякую эвристику. Так как логин одного и того же пользователя без логаута каждые 5 секунд включал кучу алертов и писал еще в десяток журналов, то всё это снежным комом росло и в базе, и в файловом хранилище. Ну и для полного счастья самого юзера нахардкодили не зная о политиках безопасности – через месяца два всё бы встало из-за автоматической блокировки.
Еще один частый кейс – это попытки интегрировать сторонние продукты. Умелые продавцы расскажут вашему клиенту, как удобно работать с «вот этим новым умным» терминалом/планшетом/мобильным приложением. И у них уже всё готово, вот и REST API с JWT и HTTPS – просто и надёжно, только бери и запускай. Основная проблема в том, что те, кто продают, не понимают ограничений реального производства и существующих процессов. А те, кто покупают, не понимают реальных возможностей продукта и ограничений информационных систем. Основные просчёты: сертификации, безопасность, анонимность, необратимость. В E-com можно отменить заказ, вернуть деньги клиенту и ничего не потерять. А вот приготовленный капучино обратно в машинку не засунешь, так же, как и не сделать перерасчёт ушедшему клиенту оплатившему наличкой. Банки давно сами стали IT, а вот розничная торговля, рестораны, отели, заправки и другие крупные компании редко имеют свой отдел разработки и людей способных оценить трудозатратность и сложность предлагаемых им чудо-решений. Так как применить инновационные гаджеты можно, но для этого необходимо перестроить все операции вокруг них.
Хотел как лучше, а получилось как всегда
Вот примерно так владелец АЗС приобрел терминал для самообслуживания своего кафе-пристройки, чтоб организовать drive through. Он знал, что интернета на станции нет, но решил, что поставить точку доступа - не проблема. В чём-то он, конечно, прав. Вот только сертификация интегрированных систем управления и биллинга не допускала наличия публичной сети. И из-за легковоспламеняющихся материалов, все устройства должны быть с определённым стандартом пожаробезопасности, иначе инспекции и страховщики вам быстро помогут ликвидировать бизнес. Так что, вместо «легкой» интеграции, пришлось выносить терминал за пределы пожароопасного периметра и пилить много чего автономно весящего в облаке с оффлайн синхронизацией (утром вносили меню и цены в терминал, вечером вбивали данные о продажах в основную систему управления). Плюс надо было докупать всякую мелочь типа планшета для кассира, отдельного кухонного принтера, на который шли заказы с терминала и т. д. А через полгода работы все это убрали – не пошла бизнес-идея, так как вместо заказа «по ходу заправки» получилось, что надо проезжать дальше в специальное место самообслуживания и забирать заказ в другой точке. Да и работники кафе не очень любили ручную автоматизацию, которая к тому же слегка обесценила несколько продуктовых метрик. За пару лет пандемии подобных историй было много.
Всё, что происходит в рамках разработки для конкретного заказчика, так же отражается и на вашем основном продукте. Помимо продуктового менеджера и его виденья будущего платформы, используют опыт и фидбек заказчиков. Так иногда платформа привносит инновации в бизнес клиента, а иногда клиенты в платформу. Основным ограничением тут служит периодичность обновлений. Цикл разработки платформы обычно медленный для реалий рынка. Об этом можно судить по особенностям разработки и развёртки системы. Клиенту же необходима динамика и time to market. Это создаёт много шума и излишней работы. Проектальный деплой идёт по желанию клиента, а платформа по плану. И на вопрос «подождать ли полгода-год и получить функицонал за Х денег или получить его за 10Х через месяц?» обычно отвечают «получить через пару месяцев за 5Х цены». Клиент разрабатывает функционал в своём проекте при поддержке разработчиков платформы. Эта фича станет доступной клиенту в короткий срок, а платформа сможет забрать её к себе на следующий релиз. Но получается, что в следующем релизе одна и та же функциональность существует на разных уровнях, что приведет к конфликтам. Значит перед выкатом релиза надо убрать её из проекта, возможно необходимо разработать/отконфигурировать кастомизацию, пересобрать и проверить. Таким образом внесение изменений в слой заказчика может просачиваться в платформу, а обновления платформы требовать изменений у клиента. Вот у нас и появилась двухсторонняя зависимость параллельных стримов, о которой при проектировании платформы скорее всего не думали. Ведь до выхода в эксплуатацию такого не происходит (на стадии разработки это легко решается перестановкой и пополнением в основном бэклоге). Такой вот слоёный и распределённый монолит.
![Просачивание сквозь бэклоги Просачивание сквозь бэклоги](https://habrastorage.org/getpro/habr/upload_files/9d2/a5e/8db/9d2a5e8dbe215282ec6f9b7cd21b076f.jpg)
К этому моменту вы уже порядком устали читать лекции чтоб удержать своих партнёров от преждевременной оптимизации. Все те дейли, на которых свежий тимлид пытаясь набрать балы у своих заявлял что-то типа: "Не вижу, почему бы трём благородным донам-синьорам не сыграть в оптимизацию там, где им хочется!". Ну и туда же менеджеры, которым кажется, что "если эти хипстеры будут делать свою работу хорошо, то и нового железа не надо!". Но вот настал момент, когда большая часть кода устаканилась и на дне технического долга зарождается жизнь. Именно, когда продукт уже захватил тысячи машин - пора подумать не о красоте, а об эффективности. Проблема любой оптимизации в её сохранении. Концепция Agile разработки в том, что вы шаг за шагом дополняете картину. Для наглядности можно использовать классическую иллюстрацию процесса. Если вы на пути к машине, но сейчас на стадии велосипеда, то не стоит вкладывать средства в титановую раму. Даже если у "конкурентов такого нет" и "с этим я могу продать много"... велосипедов... Изменений не избежать, ибо ничто не вечно, кроме перемен. Продукт жив пока в него комитят.
![Более лучший велосипед Более лучший велосипед](https://habrastorage.org/getpro/habr/upload_files/e12/056/4c1/e120564c18c49b86baff02c0f96af2a5.png)
Основные болота производительности обычно в доступе к данным. Стоит немного поискать и найдутся циклы с построчным чтением из базы, массовая трансформация для выдачи лишь пары значений, и конечно, отсутствие кэширования. Чем больше распределённая система, тем больше результат внедрения кэша - прям серебряная пуля. Ещё одним хорошим способом увеличения скорости отклика является замена расчетов в реальном времени на предрасчёт. Это особенно хорошо работает в системах, где при изменении данных можно подождать, а при чтении необходима скорость. Классический пример - разного рода деревья и графы. Допустим перерасчёт прав доступа при изменении иерархии ролей займёт время, но это можно сделать асинхронно и на мощном сервере. Потому как клиентских машин обычно много, но они слабые. И агрегировать хоть и малый объём данных, но часто – может быть накладно. А уж про большие отчёты вы уж и сами знаете – это целая индустрия с готовыми продуктами. Вот и вторая серебреная пуля – то, что можно посчитать один раз и сохранить, не стоит считать каждый раз заново. Опять-таки, благодаря статистике с реальных систем, вам точно будет ясно, где будет большой и быстрый выигрыш. Такое и клиент, и менеджер одобрят!
Так же смотрите на обработку запросов - зачастую ради скорости и гибкости в период разработки выбирают полную сериализация какой-нибудь быстрой и проверенной технологией. Однако имея статистику с прода, можно посмотреть количество запросов и ошибок. Возможно часть из них можно отсеять (сделать простую проверку) еще до ресурсоёмкой трансформации. Иногда помогает разделение запроса на части. Та часть, в которой часто ошибка обрабатывается отдельно. Тут особенно хорошо оптимизировать проектальную часть – реализацию/конфигурацию реального клиента. Платформа более гибкая и верификацию там не стоит делать строгой. А вот у клиента уже его финальная версия и там всё как раз таки жёстко. На уровне продукта, допустим, не логично делать валидацию паттерна имени пользователя, если вы ожидаете повальное использование чипов, карт и биометрии для аутентификации. А вот у конкретного клиента может оказаться будет как раз ручной ввод и частые ошибки – вот у него в модуле уже можно вставить первичную проверку без обращения к базе. Еще пулька – кончились быстрые решения на уровне продукта – загляни в проекты.
Девиз архитектора
Performance is not an issue. Эту фразу я слышал много раз, будучи одним из разработчиков платформы. Это звучало неправильно и даже унизительно. Ведь повышая свой навык в написании кода я как раз и ориентировался на эффективность. В моём понимании красивый код - минимум строк, минимум белых пятен и максимум производительности. Конечно, всё это должно быть и читаемо, но тут код ревью в помощь. Если коллега не понял, что написано — значит перемудрил. Но почти каждый раз, когда я использовал dictionary, через пару месяцев на тестах выяснялось, что в новой конфигурации возможны повторы. Я добавлял кэш, а потом появлялись сторонние процессы, модифицирующие данные и не делающие инвалидацию в моём модуле. Я строил последовательность, в которой данные трансформируются один раз и остальные классы получают уже готовую структуру, а через полгода туда вписывали новые шаги и всё сыпалось. Да, архитектор говорил, что каждый шаг получает вводные из базы и преобразует их под себя внутри, но ведь у меня было 5 классов с абсолютно одинаковой структурой - зачем же 5 раз делать одно и тоже преобразование?! Этот опыт хорошо помог мне понять, почему не стоит делать далеко идущих выводов, исходя из текущего задания. Да, иногда лучше потратить пару месяцев на оптимизацию продукта в конце, чем стелить благими намерениями дорогу из ошибок и ограничений, которых не было в дизайне. При этом не стоит путать оптимизацию с исправлением ошибок. Не надо пренебрегать подсказками анализаторов кода, указывающих на какой-нибудь случай multiple enumeration или жадные регулярки, буксующие в чуть большем объеме данных, чем на тестах.
Вы уже знаете, что на этом этапе менять инфраструктуру дорого, а значит обоснование для начальства найти легко. Если раньше вы говорили о приросте производительности в 1%, то это звучало неубедительно. Теперь этот процент, помноженный на сотню серверов, можно перевести в большую сумму денег. А значит и получить ресурс разработчиков становиться чисто математической задачей. Нам надо столько человекочасов для экономии такой то суммы в год. Начальство легко само посчитает выгоду. Тут, конечно, я не раскрываю всех карт, ведь понадобятся еще и услуги тестировщиков нагрузки, а это, зачастую, ограниченный и дорогой ресурс, автоматизация и определить threshold производительности в pipeline и так далее.
О чём еще забыли упомянуть в начале? Конечно, о том, что жизнь – не всегда рост. Да, будут новые модули и новые функции. А еще будет угасание и отмирание старого. Об этом тоже почему-то не думают. Сложность состоит не в том, чтоб удалить участки кода – для этого есть стандартные процедуры: объявление клиента в релиз плане, пометка Obsolete в кодовой базе и через пару релизов выжигаем напалмом. В теории. На практике же - есть куча документов, отчётов и регуляций, которые требуют доступа к данным из мёртвого функционала. Зачастую, чтоб удалить что-то старое, приходится разрабатывать что-то новое. Как бы раньше у вас был «редактор» и его надо заменить «просмоторщиком». Если вам «повезло», то данные могут быть защищены от удаления законом на срок в десяток лет (на моей практике в некоторых странах фискальные данные хранят 15 лет – по сроку устаревания финансовых преступлений).
Не продуманными на уровне бизнеса остаются и процедуры закрытия, замораживания, переноса. Клиент может продать свой побочный бизнес или перевезти его в другой регион. Та же проблема с данными. Нужно сохранить старые и пересчитать новую иерархию, возможно валюту, налоги и так далее. Пандемия тоже подкинула кейсов, когда бизнес не закрывается, но засыпает. Нужно уменьшить операционные расходы, оставив доступность данных. Это проще, когда весь бизнес затих, но в основном попадались требования притушить внешний рынок и сосредоточиться на внутреннем. Необходимостью стала разработка инструментов для автоматизации инфраструктуры. Так чтоб в пару кликов снизить частоту синхронизации, бэкапов, остановить операционные процедуры, подвешенные на таймер (открытие смены, закрытие операционных и финансовых периодов), автоматизация ручных (by design) процессов – выдача разрешений, остановка оборудования и т.д. (в новых реалях никого на месте просто нет).
Немного жизни
При проектировании ритейл системы было обговорено, что это нечто маленькое (для одиночных магазинчиков) и как аксиома – один часовой пояс и одна валюта. Потом был первый «успех» и продажи поскакали по миру. И сюрприз – в некоторых странах принимают больше, чем одну валюту. А некоторые магазинчики перерастают в мини сети. Даже с разными часовыми поясами. К счастью, у меня уже был подобный опыт, поэтому минимум абстракций был задан с самого начала: своя реализация для времени (особенно важно для Now), которая в начале просто обернула системные библиотеки и структура для цены (сумма, валюта), которая исключала какой-то параметр конфигурации или валюту по умолчанию. Без этого переработка всех отчётов и аудиторских записей, стала бы сложной не только в разработке, но и в миграции исторических данных. И нет, менеджмент эти абстракции не одобрил, я просто их ввёл в код напрямую. Спасибо тоже никто не сказал, но пожурили прошлое начальство за недальновидность.
Всё это к тому, что проектировать нужно будет еще много чего и то, что софт пошёл в стадию обслуживания, не значит, что он перестаёт развиваться или, что интересной работы для архитектора не будет. Более того вам предстоит честь представлять и защищать своё детище перед клиентом в реальных продакшн кризисах! Всё что вы слышали и к чему готовились, всё равно случится. В моём личном архиве: сгорел датацентр, повредили подводный кабель, наводнение уничтожило инфраструктуру телеком провайдера и конечно рейд массив умер целиком. Хотите смешного? Это всё может случиться одновременно!
Смешное
Клиент тестировал DR сайт (стандартная процедура – они переключались с основного на резервный сервер раз в месяц). В очередной тест, центр с резервным сервером сгорел, а основной админы вырубили, чтоб спровоцировать переход на резерв. Ну и конечно, рассчитывать на бесперебойную работу с одним резервом было бы глупо, вот только на дополнительных двух шёл апгрейд. Много разных команд – дитя без глаза.
Тут стоит отметить особенность таких кризисов – лишь малая часть их связана с кодом. Почти всегда вам придётся реагировать на ситуацию и окружение. Такие вещи практически не реально проверить в изолированной среде. И если экскаватор повредил кабель вашей провайдера и сеть упала, то с одной стороны – всё понятно. Вы не можете убрать причину сбоя. Но с другой стороны, так как исправление ситуации может занять не часы, а дни, то просто игнорировать и не работать – весьма противоречивое решение. В такое время клиент будет давить на вашу компанию, а компания на вас. От вас будут ждать креативный и инновационный подход. Проблема же техническая – вот и делайте так, чтоб сайт работал в оффлайне! Чудес не бывает, а иллюзия чуда стоит очень дорого. Но что-то надо делать и поэтому архитектору стоит взять команду из специалистов бизнес домейна и искать обходные пути. Оперативное решение, а не софтверное.
Прошлый опыт в копилку
Один не большой магазин попал в долгий оффлайн. Систему проектировали для поддержания работы и без сети. С этим проблемы не возникло. Вот только наша система работает не в вакууме. Можно было сделать всё кроме того, что сделать нельзя. А нельзя было обратиться к внешним службам оплаты, клуба покупателей, доставки и всякие мелочи, типа отправки нотификаций и смс. Владелец согласился не вешаться сразу (это не сеть, а частный магазин) и подумать с нами. Мы стали набрасывать и применять решения по мере их возникновения ориентируясь, в первую очередь, на скорость внедрения. Замечу, что чем больше бизнес, тем больше издержек он может понести без риска загнуться. В подобной ситуации пара крупнейших европейских сетей просто закрыла магазины, сохранив работникам зарплату, а покупателям их покупки – подарок для компенсации. Тут широкие жесты не были опцией, но и репутационный риск тоже играл роль. Первое на чём сошлись – доверие к клиенту. Кассовая система работала. Проблемы были только с финализацией транзакций (оплата, поинты, чек и всё такое). Значит вместо закрытия мы делаем заморозку (suspend) и записываем данные покупателя (имя, телефон) ручкой на чеке. Потом договариваемся с биллингом и фиделити о процессинге по телефону. Часть работников садиться на телефон и обрабатывает транзакции вручную. Чего не хватало с технической стороны – зафиксировать оплату и закрыть сделку. Продумали конфигурацию виртуального тендера и выкатили в прод через ручное управление админом. Параллельно с этим оформили заказ и вызов техника с роутером для GPRS инета. Работа магазина была восстановлена в течение получаса, а через 4 часа уже всё работало по-старому через мобильную точку доступа. Кабель починили к вечеру.
Но хуже всего – это проблемы конфигурации. Когда причина странного поведения не ясна. Вся инфраструктура работает, ошибки в коде нет, а система ведёт себя вопреки ожиданиям. Особенно сложно, когда две одинаковые по всем параметрам точки дают разный результат. Иногда, даже перенеся копию базы данных из рабочего окружения в лабораторию не удаётся воссоздать ошибки. Такой себе эффект домино. Где-то на стыке интеграций что-то идёт не так, хотя по логам всё хорошо. При разработке платформы пытаются дать запас по гибкости. И для возможной динамики изменений и для отказоустойчивости. Однако подобный подход создаёт много серых зон, когда данные/конфигурация будут уместны только в определённых условиях. Или наоборот – всё логично и правильно в каждом отдельном слое, но при наложениях получаем неожиданный эффект. Вы наверняка слышали, а может и пользовались подобными эффектами как потребитель. Те самые истории, когда можно получить бесплатный бургер или неожиданную скидку. Такие истории возникают обычно при взаимодействии разных систем и сколько бы вы не шерстили свою часть – ошибки там нет. И это очень часть вводит в ступор разработчиков и технических специалистов. Нельзя продебажить – не баг. Нельзя повторить – не баг. И так далее. Подобные истории и пинг-понг обвинений может длиться неделями. Ваша задача помочь переходу из парадигмы «повторить-починить» к «проанализировать-предотвратить». В последний раз, когда начальство посадило меня решать висяки (редко повторяющиеся критические ошибки, не закрытые больше месяца), то половину из них я решил ни разу не запустив систему. Читал логи, смотрел базу и код. Дебаг прямолинеен – из точки А в точку Б. Аналитика же эфемерна. Из логов я узнаю где проходил процесс, Точка Б уже известна (это тот самый баг). Точка А тоже известна – начало процесса. Так что надо попытаться увидеть все возможные варианты потоков событий. Иногда стоит просмотреть юнит тесты. Бывает сразу находишь слишком открытые места. Какой-нибудь отсевающий if или значение по умолчанию. Иногда же надо распутывать клубок с конца.
Но вместо того, чтоб разрешать кризисные ситуации, лучше их предотвращать. Первое правило – исправляй не только ошибку, но и причину. Не стоит лишать систему гибкости и сразу перекрыть возможность проблематичной конфигурации. Но стоит добавить в мануал описание проблематичного кейса и кинуть предупреждение на экран при попытке задать противоречивое значение. Ну и, очевидно, стоит подумать об инструментах мониторинга. Что-то уже существует на рынке. Можно с легкостью найти инструмент для резервного копирования и автоматического тестирования целостности бэкапов. Вот только проверить согласованность данных можно только зная конкретную систему. Ведь утилиты мониторинга логов тоже надо настраивать под себя. А с данными еще сложней. Желательно иметь вариант быстрой проверки целостности данных – какой-нибудь хэш только последних и только критичных данный. Эту проверку будут гонять часто. И вариант глубокой проверки с выявлением конкретных проблем – то, что админы будут запускать редко, на бэкапах и когда первая проверка выявила ошибку. Неплохо продумать экстренные/дополнительные каналы распределения и обновления данных. Во время разработки, обычно на таком экономят. Потом получается, что у вас сервер работает по принципу FIFO, а системный юзер заблокирован. Если вы просто обновите юзера в центре, то на локальных серверах это сообщение попадёт в конец очереди. Пользователь блокируется, а сообщение о разблокировки забрать не получится (см. начало предложения). В распределённых системах, особенно после восстановления, сообщения могут приходить в случайном порядке. Часто упускают необходимость постепенного восстановления. Это особенно критично в коммуникациях. Если после долго оффлайна клиентский сервер выходит на связь, то отдав ему все данные за раз можно заблокировать его работу на долго. А если таких серверов много, то и загрузить центр. Вообще большой объём данных – как прорыв плотины - те, кто выживут будут плавать в грязи.
Боевое крещение:
Через год после запуска у клиента начались проблемы с производительностью. Бутылочным горлышком стала централизованная очередь сообщений (есть много всяких MQ реализаций, и я хочу избежать product placement). Проблема переросла в кризис после инцидента с подтормаживаниями сервера даже после перезагрузки. Причина тормозов выяснилась не сразу и заключалась она в том, что очередь хранила сообщения вечно (by design), а клиент добавил в систему виртуальных получателей, которые физически не забирали сообщения. Очередь росла и после перезагрузки сервер поднимал всё то же безумное количество сообщений, что и приводило к проседаниям отзывчивости и пропускной способности. Нельзя терять данные, но никто не подумал, что делать если количество данных превышает способность сервера их обработать. Тут стоит упомянуть, что я только недавно получил повышения до должности архитектора в связи с тем, что прошлый уволился. Для меня это был первый опыт кризиса, но для клиента нет. Отношения были напряженны со всех 4 сторон: моя компания, IT отдел клиента, подрядчик интегратор и консалтинг, представлявший клиента в качестве аудитора. После первого инцидента и до выяснения причины пройдет 2 дня и работоспособность еще не восстановлена. В первые же часы мне выдали билет на самолет и встретил меня на той стороне не коллега, а адвокат. Адвокат нашей конторы. Он провёл инструктаж (с кем и о чём можно говорить без него), ознакомил с ситуацией и выдал задание. Пока я был в воздухе, архитектор клиента при поддержке консалтинга выдвинул следующий тезис: «выбранный нами продукт для сервера очереди является причиной низкой продуктивности и нам следует сменить его, оплатить изменения, развёртку и неустойку из своего кармана». Это еще не был иск, но было уже передано через адвокатов и включало сумму, сроки и список «правильных» очередей. От меня требовалось обосновать «наш выбор» хоть как-то. С прошлым архитектором мне поработать не довелось – он был на релокейшине на сайте клиента и не сильно часто общался с разработчиками. Я лично узнал его имя лишь когда сообщили об его уходе. И пока команда копалась с сервером и выясняла причины ситуации, я сидел в поте лица и выяснял всё, что мог про все популярные очереди. К полуночи я составил табличку из десятка технологий и функциональных особенностей проекта. А потом, смотря на характеристики этих очередей в версии доступной в начале разработки и на данный момент, ставил крестики там, где возможности не соответствовали требованиям. И когда к утру в этой таблице я получил крестики во всех строках (включая и новые версии этих продуктов), кроме того бренда с которым работали мы – я понял, что мой предшественник работал на совесть. На этом, правда, приключения не закончились. Когда прояснились причины, решение стало очевидным – надо очистить очередь. Вот только клиент боялся одобрить необратимое действие и требовал найти другой подход. Через давление нашего адвоката сместили директора их IT отдела, который возглавлял сопротивление (за нарушение политик эксплуатации продукта - не должно было быть не работающих адресатов), а операцию по фильтрации и удалению сообщений произвела консалтинговая компания по нашим инструкциям.
Ну и, наверное, главное, что можно сказать об этом этапе – смена кадров. Люди будут сменяться и у вас, и у заказчика. Так как количество разработки уменьшается лишь ближе к концу жизни, а критичность и сложность изменений растёт, то в команде всегда будут спецы и новобранцы. Мидл практически исчезает как класс. В роли архитектора, при правильной передаче знаний и работы, у вас могут появиться протеже. Официально или нет, но эта стадия идеально подходит для новичков. Есть кому обучить, есть уже готовое решение, есть много легких задач (те, что вписываются в текущую парадигму), но и сложные не исчезают (те, что с архитектурой не согласуются). Я вот так и попал на должность. Как опытный разработчик я стал техлидом и отвечал за дизайн простых частей пазла. Со временем на меня стали кидать больше задач по проектированию новых модулей и исследования критических багов (обычно сложная часть – понять, где и в чём проблема). Когда встал вопрос кем заткнуть дыру, образовавшуюся после ухода текущего архитектора, то выдвинули меня. Правда не официально – меня просто пихали на все совещания как «ведущего технического специалиста». Получить звание без личной беседы с менеджментом (при этом пришлось перепрыгнуть через прямого начальника) не получилось.
На фоне вялой текучки персонала и того, что вы уже не одну собаку съели в этом бизнес домейне - пора дойти до осознания, что архитектура — это не только в код, но и в бизнес. Обычно продуктовым менеджерам нужна помощь в определении четких метрики поведения пользователей и использования системы. Ваши знания связей оболочки и внутренностей дают фору в определении быстрых и дешевых решений. Какие ошибки указывают на проблемы системы, а какие на неумение или не желание пользователей с ней работать. Какие превентивные меры можно реализовать, дабы защитить систему от недоброкачественного использования. Что можно проверить прототипированием, а что не опасно вынести в А/Б тестирование. Тут, кстати, целое непаханое поле для сбора и обработки информации с помощью машинного обучения. Просто бюджет и ресурсы на эту, хоть и хайповую тему, вам не выделят. Но если вы понимаете, что ищет клиент и как не напугать расходами, то сможете продать идею и своим и клиенту. Если, конечно, и вам и разработчикам хочется запустить свою нейросеть.
А таки зачем это вам? Когда проект оживает, архитектура тоже не может оставаться статичной. Эволюционирует ли она или будет просто гнить и разваливаться – вот критерий, который определяет - хорошо ли вы работали на первых этапах и насколько хорошо усвоили уроки прошлых «успехов». Но определяет успех архитектуры и лично ваш, не устойчивость и не гибкость. А то, насколько хорошо об этом знают и используют! И никто, кроме вас, не знает систему лучше и не заинтересован в максимальной утилизации возможностей. Я уверен, что есть тысячи уникальных решений и сложных систем, о которых мы даже и не слышали. И очень жаль. С другой стороны, тех кого пиарят и приглашают на всякие вебинары, забивают медийные потоки однообразной информацией («как и почему» в десятке топовых самодостаточных компаний). Очень интересно послушать про технологии и решения каких-нибудь поисковиков или социальных сетей. Но в мире материальных продуктов вам не нужен еще один поисковик или соц.сеть. И конкурировать с каким-нибудь классифайд или рекомендационным сервисом в энтерпрайзе тоже вряд ли захотят (по экономическим причинам). Получается, что есть куча данных по проектированию систем и инструментов, которые вам не придётся разрабатывать. И минимум доступного опыта/советов, которые пригодятся в реальной работе.