Сегодня мы продолжим говорить о переходе с монолита на микросервисы. Многие задумываются над этим, когда наступает необходимость, но не все знают, как и с чего начать. В компании Авито сейчас как раз решают эту задачу и готовы поделиться своим опытом, поэтому рассказ пойдет от имени их специалиста.
В предыдущей части Микросервисы для чайников: как на них перейти с монолита с нуля. Часть 3 я рассказал про API Gateway и межсервисные взаимодействия. Можете прочитать об этом подробнее, а мы пойдём дальше.
Меня зовут Семен Катаев, я работаю в Авито над процессом перехода от монолитной архитектуры к микросервисам. Переход у нас все еще продолжается, но мне уже есть чем с вами поделиться. Это краткий обзор того, с чем придётся столкнуться, если вы задумались над созданием надежного, масштабируемого, распределённого приложения.
Service proxy
Предположим, протокол для общения между микросервисами вы выбрали. И один ваш микросервис запрашивает второй по API:
Конечно, мы можем договориться и надеяться, что все инженеры будут честно прокидывать trace ID, покрывать межсервисные взаимодействия метриками и мониторингами, настраивая алерты. Но если у вас 400 инженеров, то договоренности быстро забываются, теряются или ломаются. Ещё их невозможно обновлять и менять, потому что придется вносить изменения в тысячу микросервисов — это дорого и долго.
С помощью паттерна Service proxy у каждого инстанса микросервиса поднимается sidecar proxy, и весь трафик роутится через него. То есть у каждого экземпляра сервисов этот sidecar proxy локально собирает информацию, агрегирует и сбрасывает в какое-нибудь хранилище. Например, централизованно собирает у каждого сервиса все трейсы межсервисных взаимодействий и отправляет их в систему хранения трейсов по Open Tracing протоколу. Не изобретайте свои Service proxy. Посмотрите на фонд Cloud Native Computing Foundation и вы увидите готовые Service proxy, которые легко встраиваются в любую инфраструктуру, будь то Kubernetes, Mesos или Docker Swarm:
Мне больше всего нравится Envoy (на С++) и Traefik (на Golang). Это самое правильное место для выполнения retry, secure breaker, tracing, metrics, и monitoring.
Tracing
Для трейсинга Фонд Cloud Native Computing Foundation также предлагает много инструментов, которые также легко интегрируются между всеми вышеперечисленными:
Например, мы у себя взяли Jaeger. Он из коробки подключился к Service proxy и зашел в Kubernetes. Это готовые кирпичи, из которых можно усилить вашу микросервисную архитектуру.
Так выглядят трейсы у нас:
По request ID мы можем не только восстановить хронологию, какие сервисы были задействованы (у нас, например, на карточке объявления 50 микросервисов). Трейсы можно расширять из приложения. То есть дополнять их из самого кода приложения. Например, обернуть запрос в БД таймингом либо в походы во внешние ресурсы, либо просто оборачивать таймером тяжелые задачи, помечать их Request ID и отправлять в систему хранения tracing.
Service mesh
Так как межсервисные взаимодействия вышли на первое место, то мы, конечно, можем договориться, что в каждом из тысячи микросервисов будем использовать одну Service proxy. И надеяться, что инженеры будут это делать. Но можно пойти дальше и использовать пул инструментов Service mesh, который будет централизованно оркестрировать всеми прокси:
В Авито 10 тысяч прокси, и мы из командной строки управляем ими для всех сервисов. Например, можем запретить ходить в этот микросервис всем, кроме одного микросервиса, либо централизованно управлять их расположением. Я могу сделать А/В тесты между микросервисами или Canary релизы для них. Это централизованный пульт управления для всех прокси.
Шаблоны сервисов
Итак, мы с вами посмотрели множество инструментов для построения микросервисной архитектуры.
И мы начали создавать шаблоны микросервисов на php, go, python, nodeJS — основных языках из нашего техрадара. Мы сделали их максимально платформонезависимыми. В коде шаблона микросервиса нет ни слова про Kubernetes, Service proxy или Service mesh. Есть только app.toml — описание микросервиса:
Здесь есть название микросервиса, по которому определяется контроль доступа, и всё это идет в метрики и мониторинг. В сервисе engine описывается, на каком языке написан микросервис и его размер, чтобы понимать, сколько ему выделять CPU или памяти. Команда может выбирать ресурсы для своего микровервиса из стандартных коробочных решений (большой, средний или маленький). Мы автоматизировали и создание БД, теперь можно записать секцию Postgres, и в продакшене автоматически поднимется база данных, также как и в dev/ staging окружениях.
Пока остановимся
Я не рассмотрел еще PaaS, database, streaming & messenging, cloud native storage, logging и многое другое, потому что для этого потребуется еще несколько статей. Например, над PaaS у нас работает целая отдельная команда.
Скажу только, что инструменты streaming & messenging вам понадобятся, чтобы построить надежную распределенную масштабируемую архитектуру. В микросервисах вы теряете возможность легко поддерживать консистентность данных, поэтому приходится идти в eventually consistency, и без готовых инструментов для streaming & messenging вы не построите надежное приложение. У себя мы используем Kafka и Pulsar.
Здесь тоже есть готовые сборки под БД для построения надежных распределенных масштабируемых решений. Есть и коробочные PaaS, например, Heroku. Есть Cloud Native storage (S3, CF, MinIO), инструменты для логирования, которые также легко встраиваются в экосистему из коробки и интегрируются со всеми остальными инструментами. Всё это вы тоже сможете найти в фонде Cloud Native Computing Foundation.
В общем, микросервис — это дорогая технология, и, если вы хотите туда идти, вам придется начать использовать множество разных инструментов. Это хороший вызов для ваших DevOps и архитекторов, и я бы советовал несколько раз подумать, прежде чем отправиться в микросервисы.
Команда «Онтико» готова помочь тем, кто потерял работу из-за санкций и их последствий.
Заполните анкету и её увидят более 100 потенциальных работодателей.
Если у вас есть друзья, которым актуальна помощь, перешлите им это сообщение.