Привет, Хабр! Познакомьтесь с Андреем Черновым, архитектором микросервисов Java в СберТех.
Это третья часть материала о том, как мы разрабатываем Platform V SessionsData — высокопроизводительное распределенное in-memory хранилище для общего контекста запросов сеансов ключ-значение. В первая часть Я объяснил, почему мы решили создать собственный микросервис, и в второй Как добиться высокой доступности услуги? Сегодня мы поговорим о разработках, которые помогут нам в дальнейшем развитии Platform V SessionsData.
Contents
Платформа V DataGrid вместо СУБД
Я начну с отказа от базы данных и постоянного хранилища в целом. Но сначала расскажу, почему мы решили вообще отказаться от БД.
Во-первых, мы храним только записи активных сессий для нашей админки, самих данных там нет. Поэтому они не критичны для нашего сервиса. Если сбросить базу, мы просто не увидим активных сессий в админке. Вот почему ранее мы заменили синхронные вызовы базы данных асинхронными вызовами, которые я обсуждал во второй части.
Во-вторых, сеансы длятся недолго: в среднем 5 минут. Поэтому постоянство при хранении этих данных не требуется.
В-третьих, записи базы данных компактны и помещаются в память сервера.
Поэтому мы планируем заменить базу на Платформа V DataGrid — это решение для распределенного хранения данных, основанное на Apache Ignite и обновленное до корпоративного уровня с точки зрения безопасности и отказоустойчивости.
Вместо выделенного кластера Ignite мы создадим свой. Используя несколько jar-файлов DataGrid Platform V, мы создадим сервис-сервис — сервант, каждый узел которого станет узлом Ignite. Сами эти узлы образуют кластер Ignite в Kubernetes. Пока мы планируем использовать стандартную топологию «кольцо» и режим кэширования REPLICATED, чтобы каждый узел в кластере имел полную копию данных.

Мастер свяжется с сервантом через REST API, доступный через входной шлюз с балансировкой Round Robin. Это нужно для гибкости: у мастеров не будет подключения к БД, а сервант при одних параметрах может Ignite, а при других использовать БД по-прежнему.
Избавившись от СУБД, мы окончательно защитим себя от ее сбоев, от архитектурной избыточности, а кроме того, сможем сэкономить. А потом расскажу об доработке, которая поможет сделать наш сервис еще безопаснее для потребителей.
Авторизация доступа к данным
Крупные компании работают с большим количеством микросервисов. И каждый из них должен защищать свои контракты при работе с данными в Platform V SessionsData: другие сервисы, знающие имя раздела данных, могут его прочитать или модифицировать. Возьмем абстрактный пример: микросервисы «Билеты» и «Маршруты» могут иметь общие разделы данных, и они не хотели бы, чтобы кто-то еще имел доступ к этим данным.
Для защиты доступа к данным возьмем единый сервис авторизации на базе Open Policy Agent, который является частью продукта V IAM-платформа, где он был повышен до корпоративного уровня с точки зрения безопасности и отказоустойчивости. При этом субъектами прав доступа будут не конечные пользователи, а микросервисы, работающие на него «под капотом». Как это будет работать: после развертывания каждый микросервис импортирует политики доступа для своих разделов в сервис авторизации.

При доступе к разделам наш мастер-сервис обращается к сервису авторизации REST API и получает ответ, указывающий, авторизован доступ или нет. Служба авторизации сверяет доступ со всеми импортированными в нее политиками.

Политики, специфичные для этого инструмента авторизации, написаны на декларативном языке Rego. Но платформа V использует общую политику, написанную на Rego, которая просто интерпретирует файлы политик JSON ACL с политиками. Они выглядят так:

Здесь, в микросервисе tickets
(билеты) имеют право на чтение и запись раздела pricesPerKilometer
(цена за километр).
Что произойдет со временем задержки мастер-сервиса, если он будет вызывать сервис авторизации для каждого клиентского запроса? Мастер будет кэшировать ответы от службы авторизации. Они статичны и могут изменяться только при повторном развертывании служб. Комбинаторное число возможных ответов также невелико и легко укладывается в память мастера.

Идеальный вариант — никогда не аннулировать этот кеш. Лучше всего периодически обновлять его асинхронными обращениями к службе авторизации. Таким образом длительность задержки наших мастеров практически не увеличится после прогрева кеша. А значит, благодаря авторизации наш сервис станет еще безопаснее для потребителей.
«Неклиентские» сеансы
Одна из наших целей — упростить работу с загруженными постоянными хранилищами. Для этого мы предложили специальные сеансы, не привязанные к конкретным конечным пользователям. При создании такой сессии любой микросервис может задать любое время жизни данных. Эти длительные сеансы можно назвать «неклиентскими», «сервисными» или «техническими» — все дело в них.
Приведу интересный пример. Предположим, что при создании клиентских сессий в них загружаются редко изменяемые справочники. Это позволяет вам обращаться к постоянному хранилищу только один раз за сеанс. Но решение можно оптимизировать, если все директории хранилища загружаются в «неклиентскую» сессию и периодически обновляются асинхронным воркером. Тогда при создании каждой клиентской сессии будет достаточно просто перенести нужные каталоги из «неклиента», то есть из ОЗУ в ОЗУ, не обращаясь к диску.

Например, если клиентские сеансы создаются в службе очень часто, каждую минуту выполняется 100 500 обращений к постоянному хранилищу каталогов. А при использовании «неклиентского» сеанса это всего один вызов в минуту от асинхронного агента обновлений. Загруженные постоянные хранилища скажут за это «спасибо».
Автоматический впрыск коляски в бытовом обслуживании
И напоследок расскажу о наших планах по настройке slave sidecar оператором Kubernetes. Как я писал в вторая часть в разделе «Неконтейнерное хранилище» у нас теперь есть вспомогательная коляска в контейнере внутри потребительских модулей, которых может быть очень много. Они подключают нашу коляску к подам согласно инструкции:
• вставьте описание вспомогательного контейнера sidecar в развертывание:

• вставить описание томов для нашего sidecar в Deployment:

• добавить в свой дистрибутив конфигурационный файл с параметрами запуска sidecar (после развертывания трансформируется в ConfigMap):

• Добавьте в свой дистрибутив ConfigMap параметры поведения sidecar во время выполнения:

Делать это вручную — обычное дело, и могут быть допущены ошибки. Особенно учитывая, что скопированные части YAML могут меняться при изменении версии ведомого сайдкара.
В то же время мы хотим предоставить потребителям с низкой нагрузкой дополнительную возможность работать без нашей вспомогательной кэширующей вспомогательной машины. В этом случае наша клиентская банка в потребительском приложении сразу же получит доступ к основному хранилищу.
Поэтому мы планируем сделать оператор Kubernetes, который будет внедрять наш sidecar в потребительское развертывание. Это облегчит их работу и позволит легко подключать и отключать нашу коляску. Пользователю останется только добавить аннотации к развертыванию для нашего оператора. Включите индикатор sidecar и задайте его параметры:

Или просто отключить коляску. В этом случае потребитель изменит URL-адрес локального хоста для связи с подчиненным на основной URL-адрес в своих настройках:

Оператор будет следить за появлением каждого нового развертывания в пространстве имён потребителя и внедрять туда slave sidecar, если это указано в аннотациях.

Это решение позволит потребителям легко подключать и отключать нашу коляску, не выполняя рутинной работы.
Краткое содержание
В этой и предыдущих статьях я рассказал, как мы разрабатываем собственный продукт Platform V SessionsData, который помогает микросервисам Сбера хранить данные клиентских сессий. При этом Platform V SessionsData отлично справится с аналогичными задачами в приложениях вне Сбербанка.
Надеюсь, мой рассказ был вам полезен. Спасибо за внимание и до скорой встречи!