Друзья, привет! Если у вас так же много разработчиков как у нас, то и им, возможно,  стало тесно стоять в очереди на deploy в монолите. А значит, вы можете решить перейти на микросервисную архитектуру и дать каждому игроку свой мяч каждой команде свой микросервис.  В микросервисной архитектуре вы столкнётесь с новыми проблемами, которые не встретишь в монолите. Много сервисов означает много узлов отказа, а значит теперь вам придется следить за их стабильностью как за единым целым. Ещё много одинаковой логики по подключению к хранилищам и отправке метрик. И это только начало списка. Решить часть этих проблем вам поможет IT-платформа PaaS — техническое решение и команда, которая его развивает и поддерживает. Платформа: помогает пользователям не отвлекаться от бизнес задач: не делать свои версии адаптеров к хранилищам и отправку метрик; стандартизировать технологии и решения в компании и тем самым экономить усилия на поддержку инфраструктуры; автоматически предупреждать проблемы стабильности; следить за всеми микросервисами как за единой системой. Это вторая статья из цикла, посвященного PaaS. В первой статье мой коллега, Александр Ермолаев, рассказал, с каких инструментов и принципов мы начинали делать платформу в далеком 2020-м. Меня зовут Дмитрий Лукиянчук, и я руковожу отделом в IT-платформе СберМаркета. В этой статье я сделаю обзор инструментов, которые есть у нас сейчас, спустя 2,5 года, и какие задачи эти инструменты решают. Вы узнаете, что вам нужно будет сделать, если вы сами решите взяться за построение платформы. А если у вас уже есть своя платформа, то вам будет интересно найти 10 отличий в своей и нашей реализации. Последующие статьи цикла подробно расскажут об описанных здесь инструментах по отдельности. Технологический стек Шаблон и библиотека микросервиса sbm-cli: Управление сервисом из консоли CI/CD pipeline Deploy Внутренний портал разработчика Grafana service dashboard и алерты Поиск по всем сервисам и сбор статистики Чат поддержки Документация Заключение Сейчас наша платформа поддерживает работу с четырьмя языками: Golang — основной язык для новых микросервисов. Достаточно простой и выдерживает большую нагрузку во время высокого спроса от наших пользователей на доставку из любимых магазинов. Ruby — наш монолит был написан на Ruby и у нас большая команда разработчиков на этом языке. Благодаря платформе они могут быстро создавать новые микросервисы. Python — основной язык наших специалистов по машинному обучению.Для python, кроме шаблона «микросервиса-сервера», планируем сделать ещё и «шаблон-airflow» для описания pipeline для ML. JavaScript — язык для frontend-сервисов. Для сохранения данных мы предоставляем библиотеки и инфраструктуру для следующих хранилищ: Postgres, если нужна реляционная база данных. Redis для кэша, синхронизации задач между экземплярами сервиса и иногда как key-value хранилище. Clickhouse, если нужна колоночная база данных. Flipt для feature flag. В качестве транспорта используем три технологии: Protobuf over Kafka. Для асинхронного взаимодействия между сервисами используем Kafka, сообщения кодируем в формате protobuf.  Для работы c Protobuf over Kafka в командной строке выпустили в open source утилиту protokaf. gRPC — для синхронного взаимодействия между сервисами.  Для моков gRPC-запросов мы выпустили в open source gRPC Wiremock. О нем Никита Смирнов из моей команды рассказывает в статье Как мы сделали grpc-wiremock: сервис, создающий мок-сервер для ваших контрактов в одну команду. HTTP — для выставления API наружу -для web, mobile клиентов и внешних партнерских сервисов. Для описания взаимодействия следуем API First подходу: сначала пишем контракт, затем генерируем из него код сервера и клиента. Это позволяет следить за взаимодействием сервиса и поддерживать код клиента в актуальном состоянии. Подробнее, читайте о подходе в статье моего коллеги Саши Сусикова Трудности перевода. Как научить микросервисы общаться и не ссориться. Немного о нашей инфраструктуре: Kubernetes — здесь живут наши сервисы. Istio — используем для контроля сетевого взаимодействия: rate limiter, circuit breaker, маршрутизация запросов по заголовкам и прочее. Victoria metrics и Grafana — для сбора, хранения и отображения метрик. Kibana — для поиска по логам. Jaeger — для анализа трасс сквозных запросов. Совет: Когда выбираете технологии для своей платформы, держите в уме, что добавление каждого языка, технологии или компонента в платформу ведет к умножению функционала и стоимости поддержки не только для платформы, но и для всей компании. Поэтому не гонитесь за возможностью поддержать как можно больше и не добавляйте новые технологии без веских причин. Оценивайте затраты и выгоды. Пользовательский путь в платформе начинается с создания микросервиса. Чтобы пользователям было проще разрабатывать разные микросервисы, а вам ими управлять, нужно, чтобы они были одинаковы насколько это возможно. Поэтому первый компонент, который вы захотите сделать — шаблон микросервиса. Он помогает достичь сразу три цели, обозначенных в начале статьи. Помогает пользователям не отвлекаться от бизнес задач — не делать свои версии адаптеров к хранилищам и отправку метрик. Стандартизировать технологии и решения в компании и тем самым экономить усилия на поддержку инфраструктуры. Автоматически предупреждать проблемы стабильности. В самом простом виде шаблон — это git clone репозитория-скелетона с последующей заменой названия и путей на название и пути сервиса. Но представьте: пользователи создали несколько сервисов из вашего шаблона, прошла неделя, и в ядре шаблона вы обнаружили баг, теперь вам нужно сделать merge request в каждый сервис!  Поэтому вы захотите всё, что только возможно, вынести в импортируемые зависимости. Их можно обновлять одной командой менеджера пакетов.  Ещё вы захотите отделить файлы ядра, оставшиеся в сервисе, от пользовательских. Например, пользовательские gitlab-файлы. Это позволит вам в будущем обновлять файлы ядра простой заменой. Наш шаблон микросервиса состоит из четырех частей: Стандартные каталоги, в которых пользователи размещают бизнес логику. Конфиги с описанием используемых хранилищ, переменных и сведений о сервисе. Импорта нашей библиотеки — она содержит объект приложения, пакеты транспорта и хранилищ, функции-помощники. Каждый пакет библиотеки отправляет метрики, пишет логи, задает настройки по умолчанию, улучшающие стабильность сервиса. Импорта конфигурации пайплайна gitlab — подключает задачи, которые будут запускаться на ветках в gitlab. Довольно быстро вы решите, что пользователям неудобно пользоваться длинной инструкцией и захотите дать им возможность создавать сервис одной командой. Поэтому в СберМаркете мы сделали sbm-cli — консольный клиент для создания сервиса и других сценариев работы с ним. sbm-cli позволяет создать сервис и обновлять его: $ sbm-cli service create https://path/to/gitlab/repo — чтобы создать сервис; $ sbm-cli service upgrade — чтобы обновить платформенную библиотеку и ядро шаблона в сервисе. sbm-cli дает возможность запустить сервис локально в playground, нашем решении на основе docker compose: $ sbm-cli service up — запуск сервиса в docker compose; $ sbm-cli service status — получение статуса playground и подсказок для обращения к сервису и хранилищам; $ sbm-cli service down — остановка. Подробно про playground смотрите в моем докладе на PaaS Meetup. sbm-cli предоставляет инструменты для ежедневной разработки: создание и применение миграций; генерация серверного кода; добавление и генерация клиентов для общения с другими сервисами. Кстати, возможность генерировать серверный код и клиенты мы получили как раз благодаря применению API first подхода. О нем я писал в разделе «Технологический стек». После того как сервис создан, начинается ежедневная работа с ним. В сервисе есть файл .gitlab-ci.yml. Он импортирует в себя задачи для исполнения в базовом gitlab pipeline. Также, он импортирует файл .gitlab-ci-usr.yml, лежащий рядом. В этот файл пользователь может добавлять свои задачи. Базовый gitlab pipeline реализует flow работы с git для совместной разработки сервиса и контроля качества. Flow работы с git у нас состоит из трех итераций: Pipeline ветки: путь от написания кода локально до деплоя на фича стейдж и мержа в мастер ветку. Pipeline мастера: путь от мержа в мастер ветки до деплоя на стейдж и создания релиза. Pipeline релиза: путь от создания релиза до деплоя в прод. Pipeline каждой итерации включает в себя: прогон автотестов и линтеров: юнит тесты, тесты с playground, контрактные тесты; линтеры на код; валидация конфигов; проверка свежести версий библиотек и docker-образов; проверка кода скриптами безопасности; сборка кода — собранный образ используется во время deploy; deploy — для каждой итерации deploy происходит в свою среду. В prod и stage, наши сервисы живут в отдельных кластерах kubernetes. Прямое сетевое взаимодействие между кластерами запрещено. Это помогает избежать путанницы, повышает безопасность и стабильность. В prod можно деплоить только из pipeline релиза. Deploy на прод всегда несет риск — новый релиз может содержать ошибку. Чтобы уменьшить его, мы реализовали канареечный деплой на базе Argo rollouts: Pod’ы сервиса новой версии поднимаются и убираются по одному, а трафик запросов переводится на новые pod’ы попроцентно. Если это приводит к росту ошибок и нежелательному изменению метрик, то деплой останавливается и сервис возвращается на предыдущую версию.  Подробнее о том, как устроен канареечный деплой, рассказывал Антон малафеев на PaaS Meetup. У нас есть только одно окружение, повторяющее prod полностью — stable stage. В нем представлены все сервисы и там они взаимодействуют друг с другом. В это окружение можно деплоить только из pipeline мастера. Мы держим только одно такое полное окружение по двум причинам: Каждый узел в микросервисной архитектуре является также узлом отказа. Практически в любой момент времени в системе существует сломанный узел. Поддерживать один stable stage — это большая нагрузка на команду DevOps, а если каждому пользователю дать личный полный стейдж, то эта нагрузка возрастает кратно. Также, кратно возрастают затраты на инфраструктуру. Pipeline ветки позволяет задеплоить код для тестирования на feature stage — его pod’ы разворачиваются в том же кластере, что и stable stage, но трафик со stable stage на них не идет. Сам же сервис из feature stage по умолчанию обращается к сервисам-зависимостям, развернутым в stable stage. Это позволяет тестировать сервис в одиночку. Но иногда бывает нужно собрать контур из нескольких сервисов на разработческих ветках так, чтобы эти сервисы взаимодействовали друг с другом. Это можно сделать на внутреннем портале разработчика. О нем я чуть подробнее расскажу в разделе «Внутренний портал разработчика». В этом случае для каждого сервиса создается свой feature stage и все сервисы обращаются по сети друг к другу. Для взаимодействия через Kafka система создает временные топики, чтобы избежать гонки чтения между feature и stable stage.  О контуре из нескольких сервисов мой коллега Рома Шпак рассказывал на PaaS Meetup. Как вы заметили, ни один из описанных ранее инструментов не работает со всей микросервисной архитектурой как с единым целым, а задача такая перед платформой стоит. Внутренний портал разработчика как раз дает такую возможность. В нем можно% посмотреть карту взаимосвязей микросервисов — можно выбрать интересующий вас транспорт (см. раздел «Технологический стек») и сравнить реальный трафик между сервисами с объявленным в конфиге; посмотреть единый журнал событий, происходящих по всей системе — деплои сервисов, алерты и другие; развернуть контур связанных сервисов на feature stage (см. раздел «Deploy»); изучить индивидуальную карточку сервиса с информацией о нем; узнать оценку сервиса по разным параметрам: покрытию кода тестами, наличию установленных метрик канареечного релиза, конфигурации потребляемых ресурсов, попаданию в кэш, настройке индексов и другим; запустить нагрузочное тестирование на сервис — для нагрузочных тестов используем k6. Важный инструмент для обеспечения стабильности — dashboard сервиса в Grafana. Это «зрение» владельца сервиса для понимания, как сервис чувствует себя в prod окружении. Как вы помните, сервисы созданы из одного шаблона и используют одни и те же платформенные библиотеки а, значит, отправляют одинаковый набор метрик в Victoria metrics. Одинаковость этого набора позволила сделать единый дашборд, на котором можно выбрать имя сервиса и увидеть что с ним происходит: трафик запросов, нагрузка на CPU, состояние хранилищ, отдельных библиотек, runtime языка и другое. К этому dashboard’у привязаны также ссылки на более подробные дашборды по каждому компоненту. Правила алертов пользователи определяют в yml файле в репозитории сервиса. В нем они задают метрики и условия их срабатывания. Чтобы отлаживать правила было удобно, мы предоставляем библиотеку для написания unit-тестов на алерты. Время от времени для принятия решений по развитию платформы и для оценки масштаба проблем вам понадобится возможность узнать, сколько сервисов использует тот или иной функционал. Мы пользуемся для этого двумя инструментами: поиском по коду в gitlab и утилитой, которая скачивает все сервисы и анализирует их. Также, она позволяет: быстро находить сервис с нужными параметрами для тестирования фич; определять ответственных за сервис, которым нужно сообщить об изменениях в связанном функционале; собирать отчет со статистикой использования функционала; отправлять merge request на обновление PaaS библиотек во всех сервисах. Техническую поддержку пользователей мы ведем в выделенном чате в Mattermost (аналоге Slack). Там мы помогаем пользователям решить возникшие сложности, собираем проблемы для решения и идеи для реализации, узнаем, что нужно добавить в документацию. Документация платформы — это способ сэкономить время пользователей и свое: снизить количество вопросов в чате поддержки. Документацию мы ведем в Confluence. Там мы проводим пользователя по всем разделам платформы и инструментам, перечисленным здесь, даем исчерпывающие инструкции по решению его задач. На планировании спринтов платформенных команд присутствует наш технический писатель. Это позволяет своевременно дополнять документацию, фиксируя появление новых инструментов и изменения в существующих. Рассчитываю, что после прочтения моей статьи, вы удержитесь от перехода на микросервисы переиспользуете наш опыт и сможете быстрее построить собственную платформу. Или что по крайней мере вы почерпнули идеи и вдохновение для улучшения своих инструментов. В последующих статьях цикла мы подробно расскажем об описанных здесь инструментах по отдельности. Пишите в комментариях, какие инструменты и подробности вам наиболее интересны. Tech-команда СберМаркета ведет соцсети с новостями и анонсами. Если хочешь узнать, что под капотом высоконагруженного e-commerce, следи за нами в Telegram и на  YouTube. А также слушай подкаст «Для tech и этих» от наших it-менеджеров.  Юнит лид в платформе СберМаркета