TL;DR
  • В Swissquote используют архитектурные фитнес-функции, чтобы автоматически измерять, где системы соответствуют принципам SCS, а где отклоняются.

  • Проверки гоняются ежедневно по 1000+ приложениям и агрегируются на уровне команд/отделов/департаментов.

  • Требования сведены к числовым оценкам 0–1, результаты видны и инженерам, и руководителям, с историей по дням.

  • Для приоритизации ввели уровни бронза / серебро / золото как наборы обязательных проверок.

  • Подход уже даёт измеримый прогресс (например, рост доли приложений с отдельными учётными данными БД с 60% до 90% за год) и, по наблюдениям авторов, работает заметно лучше прежних попыток.

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

Несколько лет назад я написал статью о трансформации в сторону Self-Contained Systems (SCS); за эти 5 лет многое произошло, и пришло время для продолжения. Самая перспективная наша недавняя инициатива — использование архитектурных фитнес-функций (Architectural Fitness Functions) — автоматизированных, измеримых проверок, — чтобы выявлять, где системы соответствуют принципам SCS, а где от них отклоняются.

Обновление статуса в Swissquote

Прежде чем перейти к деталям этого подхода, я хочу дать немного контекста о том, на каком этапе Swissquote сейчас находится в части Self-Contained Systems. Это поможет лучше понять, с какими трудностями мы сталкиваемся и почему подход с архитектурными фитнес-функциями — многообещающий инструмент, который поможет нам продвинуться в трансформации.

Для нас, как для архитекторов, важно, что мы уточнили понимание того, почему архитектура Self-Contained Systems нам привлекательна. Эта архитектура удачно балансирует между абстрактными принципами и точными правилами, но при этом оставляет довольно много пространства для интерпретации; в нашем случае мы, вообще говоря, не следуем всем принципам, но применяем их там, где они помогают улучшать три ключевые архитектурные характеристики, которые мы определили так:

  • Отказоустойчивость: Сбои, затрагивающие одну Self-Contained System, должны минимально влиять на другие Self-Contained Systems

  • Масштабируемость: Системы должны выдерживать постепенный рост нагрузки, числа пользователей и функциональности без значительных усилий разработки

  • Автономность: Разработчики должны уверенно вносить изменения в приложения, минимально взаимодействуя с разработчиками других команд

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

Если говорить о практическом применении архитектуры SCS, мы видим, что осведомлённость среди 300+ инженеров в Swissquote о Self-Contained Systems высокая: термин SCS используется всеми в ежедневной работе, новичков обучают принципам, и в целом они хорошо понятны. Необходимость изоляции между командами не вызывает споров, и все команды прикладывают усилия, чтобы прояснять технические границы своих систем. Когда появляется новая разработка, по возможности стараются следовать принципам SCS.

Однако не всё идеально. Среди систем и приложений, которые появились ещё до внедрения архитектуры SCS, мало что изменилось. Мы снова и снова убеждаемся на практике: трансформация существующих систем идёт медленно и даётся крайне тяжело. Спустя четыре года после внедрения принципов было совсем немного случаев, когда можно уверенно сказать, что систему удалось успешно «вытащить» из исторической «мега-системы». Были несколько удачных инициатив, но в большинстве случаев всегда остаются отдельные интеграции, которые не согласуются с теми архитектурными принципами, которые мы продвигаем (классический пример — прямой доступ к базе данных внешней системы; в некоторых местах он может сохраняться, потому что использование аналогичного API недостаточно производительно или потому что такого API пока просто не существует).

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

Именно этот разрыв между осведомлённостью и измеримостью и закрывают фитнес-функции. Нам было недостаточно просто понимать, что системы не согласованы с целевой архитектурой — нам нужны были числа, причём автоматически, каждый день, по всем 1000+ приложениям.

Архитектурные характеристики и архитектурные фитнес-функции

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

Вот, например, определение фитнес-функции, соответствующей принципу SCS «Никакой общей бизнес-логики»:

# Название

AC-11 Доменно-специфичный код не разделяется между системами

# Определение

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

# Цель

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

# Как проверять

1. Собрать все зависимости
2. убрать все артефакты, которые являются API-контрактами
3. убрать все артефакты, которые объявляют то�� же идентификатор системы, что и это приложение
4. убрать все артефакты, которые объявляют в качестве идентификатора системы псевдосистему technical-libraries
5. проверить, что список пуст

На этом этапе можно отметить несколько наблюдений:

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

  • Область применения может быть на уровне приложения или системы; пример фитнес-функции на уровне системы — «Изоляция базы данных» (Database Segregation). Она считается выполненной, если таблицы базы данных, к которым обращаются все приложения системы, используются только приложениями этой системы.

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

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

Сейчас у нас всего 16 фитнес-функций. Не все из них уместно приводить в этой статье, потому что не все они относятся к Self-Contained Systems; часть из них на самом деле проверяет другие правила, которые существовали ещё до внедрения SCS в Swissquote и которые можно описать по тому же шаблону. Другие — специфичны для нашего технического стека, и делиться ими здесь нет смысла. Список универсальных фитнес-функций среди них такой:

  • AC-01 У приложений есть ровно одна команда сопровождения

  • AC-02 Приложения принадлежат системам

  • AC-03 Выделенный пользователь базы данны

  • AC-07 У системы есть ровно одна команда сопровождения

  • AC-08 Изоляция базы данных

  • AC-09 Сдерживание цепочек запросов

  • AC-10 Доступ к другим системам через выделенные API

  • AC-11 Доменно-специфичный код не разделяется между системами

  • AC-14 Изоляция Redis

Я не буду углубляться в детали этих характеристик ради краткости, но этот список должен помочь понять, какие именно характеристики мы проверяем. Главный вывод в том, что фитнес-функции применяются на разных уровнях и не претендуют на полноту; мы проверяем только те аспекты, для которых у нас есть высокая уверенность, что их можно реализовать точно. Пример области, которую мы пока не охватываем, — пользовательский интерфейс. Self-Contained Systems поощряют автономность на уровне UI за счёт выделенного веб-интерфейса на каждую систему и интеграции между системами через веб-технологии — ссылки или перенаправления. В Swissquote мы также используем микрофронтенды там, где нужна более тонкая гранулярность. Мы считаем, что на уровне UI тоже должны существовать характеристики, которые можно проверять, но пока мы недостаточно сфокусировались на этой области, чтобы на текущем этапе сформулировать хорошие фитнес-функции.

Использование архитектурных фитнес-функций в масштабе

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

В индустрии используются разные типы фитнес-функций и разные стратегии их внедрения; чаще всего их «встраивают» в непрерывную интеграцию, где отклонение от требований сразу становится заметным как упавшая сборка. Это отлично работает для проверок, специфичных для конкретного проекта, например для архитектурных тестов на базе ArchUnit. К сожалению, для нас такая стратегия не слишком подходит по нескольким причинам:

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

  • мы стартуем из состояния, в котором большинство проверок будет проваливаться, и мы знаем, что пройдут годы, прежде чем они начнут стабильно выполняться; использование CI фактически заморозило бы всю разработку до полного соответствия архитектуре, а мы не можем себе этого позволить

  • для некоторых проверок нужна информация, которой нет в коде, например конфигурация базы данных; это означает, что приходится обращаться к источникам данных, недоступным из среды непрерывной интеграции

Мы выбрали ежедневный автоматизированный процесс, который отправляет результаты в дашборды, доступные и инженерам, и менеджерам. (Существуют инструменты вроде Soundcheck в Backstage, но различия в детализации важны для наших задач — ниже я это поясню.)

Для внедрения таких проверок нужны данные, которые бывает непросто получить: например, какие библиотеки используются как зависимости или какие настройки применяются при подключении к базе данных. К счастью, наш технологический стек в Swissquote довольно однороден, а система конфигурации единая для всех приложений. Кроме того, мы уже много лет извлекаем информацию из нашей кодовой базы, и это позволило быстро реализовать часть проверок. Другие оказалось сложнее внедрить, потому что для них требовалось собирать данные из дополнительных источников — например, из распределённых трейсов, которые нужны, чтобы подтвердить, что HTTP-запросы не выстраиваются в цепочки между системами.

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

  • фитнес-функции выполняются для каждого приложения и каждой системы

  • каждый запуск фитнес-функции выдаёт результат в виде числового значения от 0 (не выполнено) до 1 (выполнено)

  • для каждого уровня организации (команда, отдел, департамент) значение рассчитывается как среднее по всем приложениям и системам, принадлежащим этой части организации

  • результаты сохраняются в историю: по одной точке на каждый день (как «сырые», так и агрегированные результаты)

Это позволяет предоставлять руководству верхнего уровня информацию вроде: «по вашему участку технического ландшафта доля приложений, соответствующих требованиям функции F1, выросла с 50% до 60% за последние 4 недели».

Оценки присутствуют на каждом уровне организации в виде значения от 0,0 до 1,0
Оценки присутствуют на каждом уровне организации в виде значения от 0,0 до 1,0

Проведение изменений в масштабе

На этом этапе мы реализовали важную техническую часть фитнес-функций: мы умеем их измерять и давать обратную связь по результатам. Но всё ещё не хватает одного — приоритизации. Это критично, потому что изменения, которые мы пытаемся продвинуть, скорее всего займут годы, и их нужно делать параллельно со всеми остальными изменениями, которые напрямую создают ценность для бизнеса. Если мы хотим добиться успеха, нам нужно определить цели так, чтобы сначала фокусироваться на самом важ��ом, с графиком, достаточно реалистичным, чтобы сохранять темп в долгую. И, пожалуй, самое сложное — нам нужно очень ясно донести эти цели и быть достаточно убедительными, чтобы люди в них поверили и действительно старались их достигать.

Мы организовали фитнес-функции в трёхуровневую модель:

  • уровни — «Бронза», «Серебро» и «Золото». (Системы ниже «Бронзы» относятся к уровню «None», без уровня)

  • уровень задаётся набором фитнес-функций

  • уровень присваивается для каждого технического или организационного уровня: приложение, система, команда, секция и департамент

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

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

На практике, в нашем случае уровни определены так:

Бронза

  • AC-01 У приложений есть ровно одна команда сопровождения

  • AC-02 Приложения принадлежат системам

  • AC-03 Выделенный пользователь базы данных

Серебро

  • AC-07 У системы есть ровно одна команда сопровождения

  • AC-08 Изоляция базы данных

  • AC-09 Сдерживание цепочек запросов

  • AC-14 Изоляция Redis

Золото

  • AC-10 Доступ к другим системам через выделенные API

  • AC-11 Доменно-специфичный код не разделяется между системами

Такое группирование — стратегическое, и логика выбора уровней следующая:

  • «Бронза» фокусируется на том, что мы называем ответственностью: идентифицировать приложения, оценивать их влияние и гарантировать, что за каждое приложение кто-то отвечает. На этом уровне нет ничего специфичного для архитектуры SCS (кроме того, что каждое приложение формально закреплено за системой); по сути, это следование общим лучшим практикам на уровне приложения. Тем не менее, добиться этого уровня в масштабе для нас непросто, потому что мы целимся в полное соответствие по сотням приложений, а часть из них довольно старая.

  • «Серебро» — про отказоустойчивость и масштабируемость: достижение этого уровня означает, что система является «хозяином» своих данных и имеет такой размер, чтобы за неё могла отвечать одна команда. На этом уровне системы достаточно изолированы, чтобы масштабироваться независимо и оказывать минимальное влияние на другие системы в случае сбоев или перегрузок.

  • И наконец, «Золото» — это автономность: на этом уровне команда может развивать систему с минимальными трениями с другими командами благодаря корректной интеграции функциональности с другими системами (например, через API, спроектированные специально для межсистемных интеграций).

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

Результаты говорят громче прежних попыток. Доля приложений с уникальными учётными данными для базы данных выросла с 60% до 90% всего за один год — а это изменение потребовало, чтобы сотни инженеров согласованно перенастроили сотни приложений. Мы всё ещё на ранней стадии применения этой стратегии, но она уже показывает себя намного эффективнее всех предыдущих попыток, и нам очень интересно, как эти показатели будут меняться дальше!

Заключение

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

Если говорить об архитектуре, измерять разрыв между желаемым и текущим состояниями непросто, но мы считаем, что нашли многообещающий подход в архитектурных фитнес-функциях. Они превратили расплывчатые принципы в ежедневные метрики, стратегические цели — в отслеживаемый прогресс, а абстрактные требования — в конкретные результаты, вроде скачка с 60% до 90% в настройках работы с базой данных. Мы твёрдо верим, что фитнес-функции станут ключевым инструментом: они подсветят проблемные зоны, где командам сложно применять Self-Contained Systems, и покажут, куда нам, как архитекторам, нужно направить усилия, чтобы не потерять темп.

С этим новым инструментом в распоряжении мы теперь лучше подготовлены вести трансформацию инженерной организации Swissquote в сторону Self-Contained Systems. Впереди ещё долгий путь, но мы уверены, что наши инженеры продолжат двигаться к этой цели.


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

А чтобы узнать больше о формате обучения и задать вопросы экспертам, приходите на бесплатные демо-уроки:

  • 21 января, 20:00. «Мониторинг: как понять, что твой сервис болен». Записаться

  • 29 января, 20:00. «CI/CD: 90 минут от платформы до конвейера». Записаться