Привет, Хабр! Я работаю в должности CTO Департамента развития платформ розничного бизнеса.
Раньше у нас был единый и большой департамент, который отвечал за разработку всего интернет-банка и мобильного банка. Он состоял из отделов, через которые проходили все разрабатываемые продукты и сервисы. Последовательное согласование тормозило жизненный цикл продукта, в частности Time to market.
Было принято решение поменять модель — перейти к кросс-командной организационной архитектуре, когда каждая команда является самостоятельной единицей, может делать End-to-end-разработку от начала сбора требований до разработки и эксплуатации на продакшен.
Платформенно-сервисная архитектура в рамках подразделения разработки отлично подходит для создания эффективной и хорошо управляемой ИТ-инфраструктуры.
Было выделено 4 основных цели:
Платформа в нашем банке — это технологическая основа, приводящая команды разработки к единому техническому знаменателю. Она представляет собой набор общих сервисов и библиотек, общих инфраструктуры, практик, стандартов, по которым проект проверяется на соответствие необходимым критериям для перехода к следующему этапу разработки. Это также и большое сообщество инженеров, работающих в единой среде и по общим правилам.
Платформа — это вычислительная среда, которая соединяет различные группы и позволяет получить выгоду от других участников платформы. Эта методология позволила нам разделить продуктовую и платформенную разработку. Данный подход, вращающийся вокруг задачи, позволяет участникам платформы использовать технические наработки платформенной команды для ускорения собственной разработки. Платформа позволяет убрать двойные затраты на разработку командами общих компонентов и отказаться от изобретения велосипедов.
В нашем случае платформа — это также центр технологических компетенций и центральная точка входа в системы дистанционного банковского обслуживания, т. е. в интернет-банк и мобильный банк.
Мы решили отойти от традиционного функционального деления команд: отдел тестирования, отдел аналитики, отдел разработки, отдел эксплуатации и так далее. Вместо этого появился набор кросс-функциональных команд, способных выполнить любую задачу самостоятельно в полном объёме, не теряя времени на ожидание в очереди для передачи продукта из отдела в отдел.
Раньше у нас продуктовой и платформенной разработкой занимались одни и те же люди — все отвечали за всё. Сейчас же есть выделенная технологическая команда платформы, в которой работает около 90 человек. Команда разбита на подкоманды, каждая из которых отвечает за свою часть: команда критичных микросервисов предоставления данных клиентам или же команда, отвечающая за единую платформу принятия заявок от клиентов, и так далее. При этом они, за редким исключением, не разрабатывают бизнес-функционал. И если такое происходит, это всё равно какие-то общие вещи — функции, которые используют несколько продуктов.
Платформенная команда отвечает за обеспечение стабильности работы всех систем и их доступности, разрабатывает функционал, связанный с инфраструктурой и техникой. А также поддерживает технологии, обеспечивающие параллельность продуктовой разработки.
Команда делает саму платформу, на базе которой разрабатываются бизнес-продукты. При этом платформенное подразделение следит за тем, чтобы продуктовые команды соблюдали стандарты, вели разработку согласно нашим практикам, правильно вели библиотеки и стандартным образом интегрировались с ними.
Главная задача платформенной команды — предоставлять продуктовым командам качественный платформенный сервис, который помогает быстро, самостоятельно и параллельно друг с другом разрабатывать свои продукты. Он поддерживает любую архитектуру приложений, независимо от масштаба, нагрузки и сложности.
В свою очередь для продуктовых команд, которые работают независимо от платформенной, основной критерий результативности их деятельности — достижение финансовых результатов с помощью своих продуктов. Они разрабатывают какой-нибудь новый сервис, который обеспечивает работу продукта, и оформляют его по установленным в платформе правилам. Затем самостоятельно, уже без прохождения вертикали согласований, как это было раньше, переводят исходный код в продакшен на инфраструктуре платформы. Работа продуктовых команд зависит только от их собственной скорости, их никто не блокирует и не заставляет застывать в ожидании.
Платформенно-сервисный подход помогает справиться с основной проблемой любой крупной разработки — рассогласованностью интересов команд бизнеса и ИТ. Главная цель перехода к этой методологии — улучшить скорость и качество вывода новых продуктов компании на рынок за счёт превращения лучших ИТ-практик в корпоративные стандарты.
Если работать в прежней схеме, то команда разработки вынуждена делать буквально всё, и это существенно затягивает время, необходимое для создания продукта. У неё будет расплываться фокус, потому что минимум 50 % времени надо будет тратить на разработку функционала, связанного с инфраструктурой, думать о высокой доступности. Причём, скорее всего, каждая команда будет самостоятельно это изобретать, потому что будет сложно объединить в единое комьюнити инженеров, работающих независимо друг от друга.
К тому же это такая гигантская сборка, за счет которой всё затягивается: пока все согласуют, пока каждый отдел (управление, департамент) свою визу поставит, пока это всё вместе будет готово, и только после всего этого публикуется релиз.
Перед нашей командой встала проблема — или продолжаем действовать как прежде и все вместе за всё отвечаем, или работаем в платформенной парадигме, когда есть выделенная техническая команда, отвечающая за инфраструктурные сервисы.
Решили пойти по второму пути: платформенные команды и продуктовые. Первые сосредотачиваются на разработке и поддержке инфраструктуры платформы. Вторые — на бизнес-функционале, новых продуктах или сервисах. Повторюсь, одна платформенная команда — это 80–90 человек, а платформ может быть несколько, то есть скорость — это дорого. Но при этом команды могут сосредоточиться на своей цели и быстро к ней прийти.
Внедрение СЦП привело к большим изменениям и в ИТ-архитектуре, поддерживающей разработку. В классической модели основную роль играет централизация процессов: над одним большим сервисом одновременно работают много команд. А в рамках микросервисной архитектуры платформы нужно разбить большой сервис на множество отдельных микросервисов, которые команды могут разрабатывать и выводить в продакшен самостоятельно. При этом продуктовая разработка избавилась от технических платформенных задач: бизнес-разработка ведётся отдельными командами, а группа поддержки платформы сосредоточивается исключительно на задачах технического совершенствования платформы, процессах предоставления общих сервисов и инфраструктуры.
Вся информационная структура банка представляет собой три слоя. Верхний слой, или каналы взаимодействия с клиентами, — это мобильный банк, интернет-банк, дашборд для кол-центра. Далее на среднем уровне находится наша сервисно-цифровая платформа, на которой размещаются продуктовые сервисы и которая защищает нижний слой от высокой нагрузки. Ниже располагаются тяжёлые системы — АБС, процессинг, транзакционное решение, главная книга учёта банка.
Сама СЦП состоит также из трёх частей: кеширующего слоя, информационных сервисов и платформы волеизъявления.
Первая часть за счёт кеширования данных предохраняет бизнес-сервисы от перегрузки — микросервисы обращаются не в бэкенд ПО, а в кеширующий слой. Там накапливаются и хранятся относительно большие (близкие по объёму к терабайту) массивы данных.
Инфосервисы — это микросервисная платформа внутри СЦП или слой интерфейсов (API), которые позволяют получить данные в любой клиентский канал. Их работа автоматизирована — они самостоятельно решают, откуда надо взять информацию. Если данные кеша неактуальны, то платформа принимает решение обратиться в систему, где хранятся данные, получает их с соблюдением требований к согласованности, завершает обработку клиентского запроса и добавляет сведения в кеш.
Третий слой СЦП — платформа волеизъявления, поддерживающая набор сценариев, описывающих активные действия клиента, например, сделать перевод, закрыть счёт, оформить кредит. Их работа стандартизирована в рамках платформы: новый сценарий подключается по определённому протоколу, за разработку и поддержку которого отвечает команда платформы. После завершения разработки сценарий интегрируют с платформой волеизъявления по специальному протоколу — и клиент получает возможность отправлять запросы этого типа.
Мы используем достаточно стандартный Java-стек: Java 21, Spring Boot, Reactor, Hazelcast для лёгких кешей. В качестве хранилища — PostgreSQL (есть даже распределённый вариант с шардированием), Kafka как основной брокер и Kubernetes в качестве платформы оркестрации.
На сегодняшний день платформа содержит сотни сервисов и сценариев, причём количество их увеличивается практически еженедельно. Продуктовые команды работают параллельно, используя готовые микросервисы и выводя в продакшен новые, которые в свою очередь могут использовать другие разработчики. Причём инфраструктурные вопросы их практически не волнуют, они автоматически решаются платформой. А продуктовая команда также автоматически начинает получать логи и метрики со своих сервисов.
Команде разработчиков, чтобы опубликовать свои сервисы, достаточно использовать определённый инструмент или оставить заявку, чтобы получить место для размещения. При этом им совершенно не надо думать о балансировке, Rate Limiter, обо всей технологической обвязке вокруг.
Для того чтобы всё происходило правильно и стандартизовано, продуктовым командам предоставляются общие библиотеки, чтобы не писать один и тот же код по десять раз. Ещё с их помощью разработчики, например, могут правильно организовать сбор логов и работу брокера сообщений Kafka.
Платформа позволяет командам также создавать свои сценарии волеизъявления и выкладывать в продакшен. При этом на платформе появляются новые API, предоставляющие возможность использовать их разными командами.
Все эти интеграционные функции выполняет платформа, которая отрабатывает сценарии или сервисы, не зная при этом к какому бизнесу они имеют отношение.
Когда множество процессов выполняется автоматически, а заложенные в платформу сервисы используются несколькими продуктами, потенциально могут возникать сложности из-за их взаимосвязей. Чтобы справиться с возможными проблемами, проводятся мероприятия контроля качества всех ведущихся разработок ПО на основе концепции Quality Gates. Она базируется на автоматических циклах проверки качества, которые устанавливают пороговые значения для продвижения продукта по конвейеру разработки. Т. е. весь процесс разработки разбивается на несколько этапов, в конце которых проводится проверка на соответствие определённым критериям. С помощью Quality Gates можно гарантировать, что команды соблюдают современные стандарты и практики ИТ.
Quality Gates основаны на чек-листах, по которым сервис должен пройти на разных этапах жизненного цикла проекта. Эти чек-листы включают, в частности, уровень покрытия сервиса тестами (должен быть не менее 70 %), тесты на совместимость микросервисов и их способность взаимодействовать.
Используется также методология проверки API first — подход к разработке серверных приложений, при котором API является наиболее важной частью продукта. Это гарантирует, что разработчики правильным образом сформулировали спецификацию интерфейса пользователя.
Такая проверка у нас максимально автоматизирована, причём проводится на ранних этапах разработки. Это предоставляет нам возможность значительно снизить стоимость исправления ошибок по сравнению с традиционным методом тестирования уже готового продукта.
Или же с помощью QG мы проверяем, что никто не сломал контракт взаимодействия между сервисами. Для этого триггерятся специальные контрактные тесты. И так далее.
Наша задача заключается в том, чтобы клиенты банка всегда получали нужный им сервис. Когда клиентов становилось больше, мы использовали подключение дополнительных виртуальных машин (ВМ), на которых стояли экземпляры сервисов. Для масштабирования у нас использовалось определённое количество ВМ, но, когда нагрузка увеличивалась очень сильно, требовалось подключить дополнительное количество ресурсов. Вот тут-то всё и тормозилось — чтобы ввести в эксплуатацию новые машины, развернуть на них сервисы, масштабировать их, ввести в балансировку клиентов, нужно было потратить до двух месяцев.
Сейчас, с переходом на Kubernetes, это делается за одну секунду. Надо зайти в консоль управления, нажать кнопку, и новая машина «подъезжает». Или должен быть настроен автоскейлер, который при превышении определённых порогов утилизации самостоятельно отмасштабирует сервисы. В принципе это простой функционал, который позволяет масштабировать наши сервисы, используя OpenShift и Kubernetes для оркестрации контейнеров и управления ими.
Но это только один небольшой пример. Для обеспечения высокой доступности сервисов, а нам требовалось достигнуть показателя в 99,9 %, потребовалось провести ряд серьёзных изменений — об этом ниже.
Для определения узких мест мы настроили постоянный мониторинг ресурсов на базе технологий визуализации данных Grafana и Prometheus, а также платформы управления логами ELK. Сразу увидели узкие места и приняли конкретные технические меры по улучшению пропускной способности и доступности. Сейчас простои сведены к минимуму. Мы следим за показателем Мean time to Repair, или в нашей терминологии «время отскока», и стараемся свести его к минимуму.
Сегодня, кроме Мean time to Repair, мы контролируем и все остальные DORA-метрики (DevOps Research and Assessment metrics), определяющие насколько реорганизация улучшила наше производство:
Практически в любой системе имеет место человеческий фактор. Например, недавно возникла проблема: коллеги решили испытать новую функцию на ограниченном количестве клиентов и никого не предупредили. Само собой, мы всё пофиксили, но для этого пришлось пройти квест.
Кроме того, мы кардинально поменяли подход к работе сервисов и к нашей инфраструктуре. У нас теперь очень большой запас по мощности. Мы используем огромное число разных инфраструктурных компонентов для балансировки запросов, при этом все они задублированы.
Например, мы используем отказоустойчивые паттерны и вводим механизм Rate Limiter, который в случае возникновения проблемы ограничивает количество запросов на доступ к ресурсу в системе от пользователя в течение определённого времени. Так же повсеместно используется паттерн Circuit Breaker, который предотвращает попытки выполнить операцию, которая, скорее всего, завершится неудачно. Это позволяет продолжить работу дальше, не тратя важные ресурсы, пока известно, что проблема не устранена. Да, клиент будет получать ошибку, но, по крайней мере, мы не будем ддосить нижележащую систему, чтобы она быстрее вернулась в строй.
Кроме того, мы теперь полностью отказались от «выкатывания» новых функций сразу на клиентов, а используем метод развёртывания сервисов только для некоторого множества пользователей или серверов при помощи технологий Blue-Green и Canary Deployment. Мы тестируем новые сервисы или функции на запасном контуре, идентичном основному продакшен-контуру. Переключаем туда трафик. Сначала испытываем на фокус-группе (например, на себе любимых), потом на 1 % всех клиентов, потом 10 % и далее 50 – 80 – 100 %. Если что-то пошло не так, то мы просто трафик пускаем обратно на старый контур, где стоят прежние сервисы. Это такой «канареечный» деплой, когда при сбое его увидим только мы, а клиенты от потери доступности не пострадают. Мы теперь умеем релизиться без влияния на клиентов, а время простоя сократилось примерно на 50 %.
Конечно, это дорого. Это избыточность, которая увеличивает затраты на нашу инфраструктуру в два раза, но зато мы получаем отсутствие влияния на клиентов и высокую доступность.
И последнее, но не менее важное. Автоматизация и GitOps.
Сегодня на продакшене никаких ручных работ не производится. Любое изменение на инфраструктуре производится мержем PR в репозиторий. За этим следит специализированный инструмент, который и применяет эти изменения. Сейчас мы очень много времени этому уделяем, стараясь избавиться от влияния человеческого фактора.
Бизнес всегда хочет больше, дальше, лучше и так далее. И в целом мы как команда СЦП эти желания удовлетворяем. Только по итогам одного квартала примерно в два раза сократилось количество простоев, а Time to market сократился в 10 раз. Параметр Cycle Time у нас составлял 50, сейчас он равен примерно 15–20. Частота релизов (Change Frequency) вначале равнялась 30, теперь она достигла планки в 100. Результаты реально серьёзно улучшились: мы чаще релизимся, меньше откатываемся и быстрее делаем свои задачи. Показатель доступности достиг уровня 99,9 %, в то время как в прошлом году он не превышал 99 %. При этом мы надеемся, что уже в этом году он будет равен минимум 99,95 %.
С продуктовыми командами отношения также в целом сложились, хотя привычка сваливать все свои беды на платформу до конца не изжита. :) Но это просто фон, который не мешает нам продуктивно сотрудничать. Мы используем показатель CSI (Customer Satisfaction Index), отражающий удовлетворённость внутреннего клиента, т. е. в нашем случае продуктовых команд. Он постоянно изменяется, и мы стараемся держать его на высоком уровне, реагируя на их замечания и прислушиваясь к предложениям.
Причём сейчас мы стали значительно ближе друг к другу. Раньше, когда структура состояла из подразделений, отделов, управлений, люди общались очень формально — с помощью заявок, писем и т. п. Сейчас у нас работает чат для платформенных техлидов, есть аналогичный ресурс для ИТ-лидеров. Т. е. коммуникации стали существенно проще и более частыми. Проблемы перестали замалчиваться и стали решаться совместно. И хотя здесь нет точных метрик, по ощущениям ситуация реально выравнивается — теперь проблемы чаще решаются без эскалации на верхний уровень.
В заключение хочу ещё раз сказать, что обеспечение параллельности разработки, высокой доступности сервисов и отказоустойчивости — это дорого. Но важно понимать баланс — за эти деньги вы получаете быструю параллельную разработку продуктов, низкий Time to market, мощную технологическую базу, высокую доступность и, соответственно, все остальные преимущества, которые выводят бизнес на другой уровень.
Раньше у нас был единый и большой департамент, который отвечал за разработку всего интернет-банка и мобильного банка. Он состоял из отделов, через которые проходили все разрабатываемые продукты и сервисы. Последовательное согласование тормозило жизненный цикл продукта, в частности Time to market.
Было принято решение поменять модель — перейти к кросс-командной организационной архитектуре, когда каждая команда является самостоятельной единицей, может делать End-to-end-разработку от начала сбора требований до разработки и эксплуатации на продакшен.
Платформенно-сервисная архитектура в рамках подразделения разработки отлично подходит для создания эффективной и хорошо управляемой ИТ-инфраструктуры.
Было выделено 4 основных цели:
- Снизить Time to market.
- Распараллелить процесс продуктовой разработки.
- Повысить стабильность работы банковских продуктов.
- Внедрить единые стандарты и практики ИТ в процесс разработки.
Что такое сервисно-цифровая платформа (СЦП)
Платформа в нашем банке — это технологическая основа, приводящая команды разработки к единому техническому знаменателю. Она представляет собой набор общих сервисов и библиотек, общих инфраструктуры, практик, стандартов, по которым проект проверяется на соответствие необходимым критериям для перехода к следующему этапу разработки. Это также и большое сообщество инженеров, работающих в единой среде и по общим правилам.
Платформа — это вычислительная среда, которая соединяет различные группы и позволяет получить выгоду от других участников платформы. Эта методология позволила нам разделить продуктовую и платформенную разработку. Данный подход, вращающийся вокруг задачи, позволяет участникам платформы использовать технические наработки платформенной команды для ускорения собственной разработки. Платформа позволяет убрать двойные затраты на разработку командами общих компонентов и отказаться от изобретения велосипедов.
В нашем случае платформа — это также центр технологических компетенций и центральная точка входа в системы дистанционного банковского обслуживания, т. е. в интернет-банк и мобильный банк.
Как организована работа в рамках платформы
Мы решили отойти от традиционного функционального деления команд: отдел тестирования, отдел аналитики, отдел разработки, отдел эксплуатации и так далее. Вместо этого появился набор кросс-функциональных команд, способных выполнить любую задачу самостоятельно в полном объёме, не теряя времени на ожидание в очереди для передачи продукта из отдела в отдел.
Раньше у нас продуктовой и платформенной разработкой занимались одни и те же люди — все отвечали за всё. Сейчас же есть выделенная технологическая команда платформы, в которой работает около 90 человек. Команда разбита на подкоманды, каждая из которых отвечает за свою часть: команда критичных микросервисов предоставления данных клиентам или же команда, отвечающая за единую платформу принятия заявок от клиентов, и так далее. При этом они, за редким исключением, не разрабатывают бизнес-функционал. И если такое происходит, это всё равно какие-то общие вещи — функции, которые используют несколько продуктов.
Платформенная команда отвечает за обеспечение стабильности работы всех систем и их доступности, разрабатывает функционал, связанный с инфраструктурой и техникой. А также поддерживает технологии, обеспечивающие параллельность продуктовой разработки.
Команда делает саму платформу, на базе которой разрабатываются бизнес-продукты. При этом платформенное подразделение следит за тем, чтобы продуктовые команды соблюдали стандарты, вели разработку согласно нашим практикам, правильно вели библиотеки и стандартным образом интегрировались с ними.
Главная задача платформенной команды — предоставлять продуктовым командам качественный платформенный сервис, который помогает быстро, самостоятельно и параллельно друг с другом разрабатывать свои продукты. Он поддерживает любую архитектуру приложений, независимо от масштаба, нагрузки и сложности.
В свою очередь для продуктовых команд, которые работают независимо от платформенной, основной критерий результативности их деятельности — достижение финансовых результатов с помощью своих продуктов. Они разрабатывают какой-нибудь новый сервис, который обеспечивает работу продукта, и оформляют его по установленным в платформе правилам. Затем самостоятельно, уже без прохождения вертикали согласований, как это было раньше, переводят исходный код в продакшен на инфраструктуре платформы. Работа продуктовых команд зависит только от их собственной скорости, их никто не блокирует и не заставляет застывать в ожидании.
Как мы шли к текущему положению вещей
Платформенно-сервисный подход помогает справиться с основной проблемой любой крупной разработки — рассогласованностью интересов команд бизнеса и ИТ. Главная цель перехода к этой методологии — улучшить скорость и качество вывода новых продуктов компании на рынок за счёт превращения лучших ИТ-практик в корпоративные стандарты.
Если работать в прежней схеме, то команда разработки вынуждена делать буквально всё, и это существенно затягивает время, необходимое для создания продукта. У неё будет расплываться фокус, потому что минимум 50 % времени надо будет тратить на разработку функционала, связанного с инфраструктурой, думать о высокой доступности. Причём, скорее всего, каждая команда будет самостоятельно это изобретать, потому что будет сложно объединить в единое комьюнити инженеров, работающих независимо друг от друга.
К тому же это такая гигантская сборка, за счет которой всё затягивается: пока все согласуют, пока каждый отдел (управление, департамент) свою визу поставит, пока это всё вместе будет готово, и только после всего этого публикуется релиз.
Перед нашей командой встала проблема — или продолжаем действовать как прежде и все вместе за всё отвечаем, или работаем в платформенной парадигме, когда есть выделенная техническая команда, отвечающая за инфраструктурные сервисы.
Решили пойти по второму пути: платформенные команды и продуктовые. Первые сосредотачиваются на разработке и поддержке инфраструктуры платформы. Вторые — на бизнес-функционале, новых продуктах или сервисах. Повторюсь, одна платформенная команда — это 80–90 человек, а платформ может быть несколько, то есть скорость — это дорого. Но при этом команды могут сосредоточиться на своей цели и быстро к ней прийти.
Внедрение СЦП привело к большим изменениям и в ИТ-архитектуре, поддерживающей разработку. В классической модели основную роль играет централизация процессов: над одним большим сервисом одновременно работают много команд. А в рамках микросервисной архитектуры платформы нужно разбить большой сервис на множество отдельных микросервисов, которые команды могут разрабатывать и выводить в продакшен самостоятельно. При этом продуктовая разработка избавилась от технических платформенных задач: бизнес-разработка ведётся отдельными командами, а группа поддержки платформы сосредоточивается исключительно на задачах технического совершенствования платформы, процессах предоставления общих сервисов и инфраструктуры.
Структура сервисно-цифровой платформы
Вся информационная структура банка представляет собой три слоя. Верхний слой, или каналы взаимодействия с клиентами, — это мобильный банк, интернет-банк, дашборд для кол-центра. Далее на среднем уровне находится наша сервисно-цифровая платформа, на которой размещаются продуктовые сервисы и которая защищает нижний слой от высокой нагрузки. Ниже располагаются тяжёлые системы — АБС, процессинг, транзакционное решение, главная книга учёта банка.
Сама СЦП состоит также из трёх частей: кеширующего слоя, информационных сервисов и платформы волеизъявления.
Первая часть за счёт кеширования данных предохраняет бизнес-сервисы от перегрузки — микросервисы обращаются не в бэкенд ПО, а в кеширующий слой. Там накапливаются и хранятся относительно большие (близкие по объёму к терабайту) массивы данных.
Инфосервисы — это микросервисная платформа внутри СЦП или слой интерфейсов (API), которые позволяют получить данные в любой клиентский канал. Их работа автоматизирована — они самостоятельно решают, откуда надо взять информацию. Если данные кеша неактуальны, то платформа принимает решение обратиться в систему, где хранятся данные, получает их с соблюдением требований к согласованности, завершает обработку клиентского запроса и добавляет сведения в кеш.
Третий слой СЦП — платформа волеизъявления, поддерживающая набор сценариев, описывающих активные действия клиента, например, сделать перевод, закрыть счёт, оформить кредит. Их работа стандартизирована в рамках платформы: новый сценарий подключается по определённому протоколу, за разработку и поддержку которого отвечает команда платформы. После завершения разработки сценарий интегрируют с платформой волеизъявления по специальному протоколу — и клиент получает возможность отправлять запросы этого типа.
Мы используем достаточно стандартный Java-стек: Java 21, Spring Boot, Reactor, Hazelcast для лёгких кешей. В качестве хранилища — PostgreSQL (есть даже распределённый вариант с шардированием), Kafka как основной брокер и Kubernetes в качестве платформы оркестрации.
Как устроена параллельная разработка и обеспечивается её качество
На сегодняшний день платформа содержит сотни сервисов и сценариев, причём количество их увеличивается практически еженедельно. Продуктовые команды работают параллельно, используя готовые микросервисы и выводя в продакшен новые, которые в свою очередь могут использовать другие разработчики. Причём инфраструктурные вопросы их практически не волнуют, они автоматически решаются платформой. А продуктовая команда также автоматически начинает получать логи и метрики со своих сервисов.
Команде разработчиков, чтобы опубликовать свои сервисы, достаточно использовать определённый инструмент или оставить заявку, чтобы получить место для размещения. При этом им совершенно не надо думать о балансировке, Rate Limiter, обо всей технологической обвязке вокруг.
Для того чтобы всё происходило правильно и стандартизовано, продуктовым командам предоставляются общие библиотеки, чтобы не писать один и тот же код по десять раз. Ещё с их помощью разработчики, например, могут правильно организовать сбор логов и работу брокера сообщений Kafka.
Платформа позволяет командам также создавать свои сценарии волеизъявления и выкладывать в продакшен. При этом на платформе появляются новые API, предоставляющие возможность использовать их разными командами.
Все эти интеграционные функции выполняет платформа, которая отрабатывает сценарии или сервисы, не зная при этом к какому бизнесу они имеют отношение.
Когда множество процессов выполняется автоматически, а заложенные в платформу сервисы используются несколькими продуктами, потенциально могут возникать сложности из-за их взаимосвязей. Чтобы справиться с возможными проблемами, проводятся мероприятия контроля качества всех ведущихся разработок ПО на основе концепции Quality Gates. Она базируется на автоматических циклах проверки качества, которые устанавливают пороговые значения для продвижения продукта по конвейеру разработки. Т. е. весь процесс разработки разбивается на несколько этапов, в конце которых проводится проверка на соответствие определённым критериям. С помощью Quality Gates можно гарантировать, что команды соблюдают современные стандарты и практики ИТ.
Quality Gates основаны на чек-листах, по которым сервис должен пройти на разных этапах жизненного цикла проекта. Эти чек-листы включают, в частности, уровень покрытия сервиса тестами (должен быть не менее 70 %), тесты на совместимость микросервисов и их способность взаимодействовать.
Используется также методология проверки API first — подход к разработке серверных приложений, при котором API является наиболее важной частью продукта. Это гарантирует, что разработчики правильным образом сформулировали спецификацию интерфейса пользователя.
Такая проверка у нас максимально автоматизирована, причём проводится на ранних этапах разработки. Это предоставляет нам возможность значительно снизить стоимость исправления ошибок по сравнению с традиционным методом тестирования уже готового продукта.
Или же с помощью QG мы проверяем, что никто не сломал контракт взаимодействия между сервисами. Для этого триггерятся специальные контрактные тесты. И так далее.
Как обеспечивается высокая доступность
Наша задача заключается в том, чтобы клиенты банка всегда получали нужный им сервис. Когда клиентов становилось больше, мы использовали подключение дополнительных виртуальных машин (ВМ), на которых стояли экземпляры сервисов. Для масштабирования у нас использовалось определённое количество ВМ, но, когда нагрузка увеличивалась очень сильно, требовалось подключить дополнительное количество ресурсов. Вот тут-то всё и тормозилось — чтобы ввести в эксплуатацию новые машины, развернуть на них сервисы, масштабировать их, ввести в балансировку клиентов, нужно было потратить до двух месяцев.
Сейчас, с переходом на Kubernetes, это делается за одну секунду. Надо зайти в консоль управления, нажать кнопку, и новая машина «подъезжает». Или должен быть настроен автоскейлер, который при превышении определённых порогов утилизации самостоятельно отмасштабирует сервисы. В принципе это простой функционал, который позволяет масштабировать наши сервисы, используя OpenShift и Kubernetes для оркестрации контейнеров и управления ими.
Но это только один небольшой пример. Для обеспечения высокой доступности сервисов, а нам требовалось достигнуть показателя в 99,9 %, потребовалось провести ряд серьёзных изменений — об этом ниже.
Для определения узких мест мы настроили постоянный мониторинг ресурсов на базе технологий визуализации данных Grafana и Prometheus, а также платформы управления логами ELK. Сразу увидели узкие места и приняли конкретные технические меры по улучшению пропускной способности и доступности. Сейчас простои сведены к минимуму. Мы следим за показателем Мean time to Repair, или в нашей терминологии «время отскока», и стараемся свести его к минимуму.
Сегодня, кроме Мean time to Repair, мы контролируем и все остальные DORA-метрики (DevOps Research and Assessment metrics), определяющие насколько реорганизация улучшила наше производство:
- Change Frequency — это частота релизов. Мы следим за тем, чтобы она повышалась.
- Cycle Time — это время от начала разработки задачи до появления её на продакшен. По сути, тот самый Time to market, только чуть более гранулярный.
- Change Failure Rate — процент развёртываний, вызывающих инцидент или снижение качества сервиса. Т.е. он определяет, как часто мы откатываемся с продакшена. Кстати, сегодня мы, по сути, уже не откатываемся, мы просто фиксим релиз и затем накатываем новую версию.
Практически в любой системе имеет место человеческий фактор. Например, недавно возникла проблема: коллеги решили испытать новую функцию на ограниченном количестве клиентов и никого не предупредили. Само собой, мы всё пофиксили, но для этого пришлось пройти квест.
Кроме того, мы кардинально поменяли подход к работе сервисов и к нашей инфраструктуре. У нас теперь очень большой запас по мощности. Мы используем огромное число разных инфраструктурных компонентов для балансировки запросов, при этом все они задублированы.
Например, мы используем отказоустойчивые паттерны и вводим механизм Rate Limiter, который в случае возникновения проблемы ограничивает количество запросов на доступ к ресурсу в системе от пользователя в течение определённого времени. Так же повсеместно используется паттерн Circuit Breaker, который предотвращает попытки выполнить операцию, которая, скорее всего, завершится неудачно. Это позволяет продолжить работу дальше, не тратя важные ресурсы, пока известно, что проблема не устранена. Да, клиент будет получать ошибку, но, по крайней мере, мы не будем ддосить нижележащую систему, чтобы она быстрее вернулась в строй.
Кроме того, мы теперь полностью отказались от «выкатывания» новых функций сразу на клиентов, а используем метод развёртывания сервисов только для некоторого множества пользователей или серверов при помощи технологий Blue-Green и Canary Deployment. Мы тестируем новые сервисы или функции на запасном контуре, идентичном основному продакшен-контуру. Переключаем туда трафик. Сначала испытываем на фокус-группе (например, на себе любимых), потом на 1 % всех клиентов, потом 10 % и далее 50 – 80 – 100 %. Если что-то пошло не так, то мы просто трафик пускаем обратно на старый контур, где стоят прежние сервисы. Это такой «канареечный» деплой, когда при сбое его увидим только мы, а клиенты от потери доступности не пострадают. Мы теперь умеем релизиться без влияния на клиентов, а время простоя сократилось примерно на 50 %.
Конечно, это дорого. Это избыточность, которая увеличивает затраты на нашу инфраструктуру в два раза, но зато мы получаем отсутствие влияния на клиентов и высокую доступность.
И последнее, но не менее важное. Автоматизация и GitOps.
Сегодня на продакшене никаких ручных работ не производится. Любое изменение на инфраструктуре производится мержем PR в репозиторий. За этим следит специализированный инструмент, который и применяет эти изменения. Сейчас мы очень много времени этому уделяем, стараясь избавиться от влияния человеческого фактора.
Взаимоотношения с бизнесом и продуктовыми командами
Бизнес всегда хочет больше, дальше, лучше и так далее. И в целом мы как команда СЦП эти желания удовлетворяем. Только по итогам одного квартала примерно в два раза сократилось количество простоев, а Time to market сократился в 10 раз. Параметр Cycle Time у нас составлял 50, сейчас он равен примерно 15–20. Частота релизов (Change Frequency) вначале равнялась 30, теперь она достигла планки в 100. Результаты реально серьёзно улучшились: мы чаще релизимся, меньше откатываемся и быстрее делаем свои задачи. Показатель доступности достиг уровня 99,9 %, в то время как в прошлом году он не превышал 99 %. При этом мы надеемся, что уже в этом году он будет равен минимум 99,95 %.
С продуктовыми командами отношения также в целом сложились, хотя привычка сваливать все свои беды на платформу до конца не изжита. :) Но это просто фон, который не мешает нам продуктивно сотрудничать. Мы используем показатель CSI (Customer Satisfaction Index), отражающий удовлетворённость внутреннего клиента, т. е. в нашем случае продуктовых команд. Он постоянно изменяется, и мы стараемся держать его на высоком уровне, реагируя на их замечания и прислушиваясь к предложениям.
Причём сейчас мы стали значительно ближе друг к другу. Раньше, когда структура состояла из подразделений, отделов, управлений, люди общались очень формально — с помощью заявок, писем и т. п. Сейчас у нас работает чат для платформенных техлидов, есть аналогичный ресурс для ИТ-лидеров. Т. е. коммуникации стали существенно проще и более частыми. Проблемы перестали замалчиваться и стали решаться совместно. И хотя здесь нет точных метрик, по ощущениям ситуация реально выравнивается — теперь проблемы чаще решаются без эскалации на верхний уровень.
В заключение хочу ещё раз сказать, что обеспечение параллельности разработки, высокой доступности сервисов и отказоустойчивости — это дорого. Но важно понимать баланс — за эти деньги вы получаете быструю параллельную разработку продуктов, низкий Time to market, мощную технологическую базу, высокую доступность и, соответственно, все остальные преимущества, которые выводят бизнес на другой уровень.