.NET Fest — Главная .NET конференция в Украине, 2 дня, 700+ участников, международные спикеры. Смотреть доклады на сайте >>
×Закрыть

Как мигрировать нагруженный проект на микросервисы: опыт маркетплейса

Привет, я — Дмитрий Немеш, СТО в компании Lalafo, волонтер в GeekHub, более 7 лет работаю с PHP/Java/Node.js. В этой статье расскажу, как мобильный С2С маркетплейс переходил на микросервисы и с какими вызовами столкнулся.

Lalafo — это приложение для покупки и продажи б/у вещей, авто и поиска недвижимости, работы и услуг. В нем применяется машинное обучение и компьютерное зрение для распознавания товаров на фото, выявления мошенников, улучшения релевантности контента. Сегодня Lalafo активен на 4 рынках, на 3 из них сервис стал мобильным маркетплейсом № 1. Сегодня проект обрабатывает более 900 запросов в секунду, и его машины нагружены на 25-30% мощности.

Изначально проект был построен на монолитной архитектуре. После детального анализа монолита оказалось, что продукт имел ряд проблем. Это проблемы как с самим качеством кода, так и с возможностью прочитать и понять чужой код, так как над проектом последовательно работало две команды.

Почему микросервисы

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

  • переписать монолит;
  • перейти на сервисно-ориентированную архитектуру;
  • перейти на микросервисно-ориентированную архитектуру.

Микросервисы импонировали больше остальных. Поэтому мы пообщались с людьми, которые уже внедрили микросервисы, с людьми которым не удалось внедрить микросервисы, и оценили с какими проблемами столкнемся. В результате решили остановиться на микросервисах.

Основные вызовы

Нам нужно было объединить 7 баз данных из 7-ми рынков в одну глобальную. Это нужно было сделать с расчетом, что все данные будут сначала объединены в одну глобальную базу данных, а потом разнесены в отдельные базы для каждого микросервиса. Также нам нужно было сохранить все связи между сущностями. Что это означает? Например, нужно было решить все конфликты ID-шников (то есть юзер под ID 1 — это 7 разных пользователей в 7 разных странах). При этом один и тот же пользователь мог быть зарегистрированным в 7 разных странах. Потом нужно было повторить старый API, чтобы все приложения продолжали работать. В Lalafo несколько миллионов клиентов, и бесшовный переход был критично важным моментом.

И в дополнение, нам нужно было сохранить SЕО трафик. Это значит, что все проиндексированные ссылки должны были остаться доступными по тем же адресам с теми же ID, что и до миграции.

Какие бывают модели микросервисов

Различают 3 модели микросервисов: звездоподобная, модель Twitter, сервисно-ориентированная. Для Lalafo мы остановились на последней и вот почему.

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

Модель Twitter— мы ее использовали. У нас весь API версионный: версия 1, версия 2 использует как раз эту модель. Есть фронт-микросервис, он работает как front controller в MVC фреймворках. Он принимает на себя все запросы, и он же их верифицирует, анализирует и перенаправляет на другие микросервисы. Все хорошо, замечательно, нам нравится, но на фронт-микросервис приходилось слишком много трафика. Поэтому возникло желание его переписать. У нас он написан на PHP, оптимально было бы перейти на Rust или Go, чтобы он работал быстрее. Хотя на тот момент проблем с производительностью не было, прежде чем переписывать его мы подумали, а может есть какой-то другой вариант? И попробовали сервисную модель.

Сервисно-ориентированная. Сервисная модель заключается в том, что сам клиент обращается в те микросервисы, которые ему нужны. Эта модель хорошо сработала для нас, правда только ее 3-я версия. С ней все отлично, кроме 2-х недостатков с которыми можно жить.

  1. Сложность администрирования. Все наши микросервисы работают в приватной сети, и к ним никак нельзя достучаться извне. Чтобы взаимодействовать с микросервисами, нужно прописать путь на балансере. На наших 24 микросервисах уже более сотни этих роутов. Что значительно усложняет жизнь сисадмину.
  2. В работе с микросервисом появляется элемент сервиса. Если микросервис занимается непосредственно одной связанной доменной областью или маленькой задачей: объявление, пользователь или еще что-то, то микросервис начинает сам определять наличие доступа пользователя к определенному ресурсу. Для этого микросервис ходит на юзер-микросервис, вытаскивает данные, проверяет их, верифицирует и после этого дает ответ. Из-за такой логики микросервисы начинают постепенно разрастаться в полноценные сервисы и заниматься тем, чем по идее не должны.

Как мы мигрировали

Когда мы решили начать разработку, нам нужно было понять, можем ли мы работать с микросервисной архитектурой. Для этого мы разработали SDK (Logs, InfluxDB, Services, Helpers, HttpClient), который помогал синхронизироваться с разными микросервисами и ускорить разработку. Также мы разработали инструменты, которые помогали работать с микросервисами в виде ORM. Все это было сделано, чтобы разработка осталась максимально похожей на привычную разработку монолита. В результате разработчикам было несложно привыкнуть к ней, так как стиль кода оставался похожим на монолитный.

Мы также адаптировали компоненты фреймворка, которые мы использовали для access control, users, логирования. В итоге разработчик использовал все необходимые компоненты как и раньше. Данный подход помог нам за 3 месяца написать полностью рабочую MVP версию проекта, который писался более 2-х лет.

Мы объединили 7 баз данных с помощью микросервиса «migrate», также он умел доливать данные. Этот микросервис отсылал всю историю старых и новых ID на микросервис «map», по которым строилась карта старых и новых идентификаторов. Это решало проблему обратной совместимости и сохранения SEO трафика. Также мы зарезервировали диапазон идентификаторов для старых данных, чтобы можно было определить, где данные с монолита, а где те, которые уже созданы в новой архитектуре. После этого мы создали еще один микросервис, который разнес данные из большой базы по отдельным базам данных микросервисов. В итоге мы получили данные, где все записи сохранили все отношения друг с другом, но имели новые ID и карту для получения данных по старым ID. Диапазон-разделитель ID помог нам понимать, какие данные нужно доставать по карте, а которые оставить как есть.

Процесс перехода

Migrate микросервис запускался для конкретной страны (рынка), переливал данные в общую базу, создавал карту связей и потом разносил данные по базам отдельных микросервисов. Следующим шагом было переключение на балансере трафика с монолита на микросервисы. В финале мы доливали данные, которые создались или изменились во время окончания первой заливки и переключения трафика.

Stack, который мы выбрали:

  • PHP 7, Yii2, Codeception;
  • Python — data-science стек для компьютерного зрения и машинного обучения;
  • NodeJS — comet server для сокетов;
  • PostgreSQL — основная база данных,
  • MongoDB, Cassandra, Google BigQuery — БД для наших кастомных аналитик;
  • Redis — кеш и сессии;
  • ElasticSearch — полнотекстовый поиск;
  • RabbitMQ, Kafka — очереди и message bus для аналитики;
  • InfluxDB+Grafana — метрики;
  • Graylog2, Zabbix — логирование и мониторинг системы;
  • GitLab, Kubernetes, Docker, CloudFlare;

В результате мы пришли к такому количеству микросервисов:

Core: user, catalog, chat, sender, moderation, payment, security, fraud.
Supplementary: page, location, SEO, translation, Migrate-app, map, mobile-api, cache, analytics, upload, file node.
AI: classify, classify-analytics, duplicates, image processing, content filtering.

После того, как ты всю жизнь писал монолиты, ты садишься за микросервисы и возникают три категории ощущений:

  1. Идеально! Ты работаешь с некоторыми из них и думаешь: «Круто, это действительно работает!».
  2. С другими ты думаешь: «Что-то не так, эти несколько микросервисов можно было объединить в один».
  3. Ты видишь, что микросервис работает плохо. И это не проблема микросервиса.

Идеальные микросервисы: translations, sender, analytics, security, upload, classify.
Микросервисы, которые хочется объединить: user, catalog, location.
Микросервисы, которые хочется переосмыслить: fraud, moderation.

Важность тестирования

С микросервисной архитектурой невозможно жить, не используя автотесты. Мы используем гибридные Codeception тесты, смесь Acceptance (REST Module) с Functional тестами — это оптимальный вариант. У нас получаются легко читабельные Acceptance тесты, простые в написании и поддержке, плюс с фикстурами и моками, как в функциональных тестах. На их прогон нужно немного времени, в связи с чем у нас быстрый continuous integration — у нас маленькие микросервисы, у которых маленькие наборы тестов, непосредственно связанные с этим микросервисом. Как только какое-то изменение произошло, continuous integration сразу же тестит это изменение независимо от ветки.

Ручное тестирование возможно только с дополнительными инструментами, такими как Postman. В последних версиях можно создавать сценарии и импортировать их, что позволяет нашим тестировщикам в сложных кейсах отсылать не шаги воспроизведения в виде таска в Jira, а сценарий для Postman. Также наша QA команда использует JMeter для автоматизации своих тест-кейсов, тестирования публичного API и нагрузочного тестирования.

Вывод:

  • автотесты — must have;
  • ручное тестирование — боль;
  • Acceptance + functional tests (REST Module);
  • Fast continuous integration.

Микросервисная коммуникация

  • REST API with http-cache;
  • Queue Rebbit MQ/Kafka;
  • Global events with Kafka (Message Bus/ Event-drive).

REST API позволяет легко организовывать, оптимизировать и версионировать коммуникацию между микросервисами. Плюс у сисадмина появляются новые инструменты для спасения нас и проекта по ночам. Если что-то пошло не так, сисадмин находит проблемный путь и подключает HTTP кэш на этот путь, проблемный микросервис практически не вызывается, но зато ответы отдает (не всегда актуальные, но это другой вопрос). Мы в это время анализируем логи, фиксим, и при этом приложение не падает.

Очереди Rabbit MQ — за год у нас не было ни одной проблемы с Rabbit MQ. Стабильно и надежно работает, только позитивный опыт. Но надо отдать должное — это заслуга того, что у нас не огромные данные в очереди.

Kafka — крутая штука. Очень напоминает очереди, но это не совсем они, это скорее система логов с возможностью обмена сообщениями. Вы подключаетесь как к обычной очереди и можете отрабатывать один и тот же ивент несколько раз, в зависимости от того, какие микросервисы подписаны на этот топик, так как у каждого микросервиса свой оффсет. Для такой реализации в RabbitMQ вам нужно один месседж бросать в несколько очередей для каждого микросервиса или перебрасывать с одной очереди в другую по мере выполнения. Пропускная способность намного выше, чем в Rabbit MQ. Сейчас мы работаем над тем, чтобы все наши ивенты автоматом попадали в Kafka.

Активные и пассивные микросервисы

Когда человек ведет сразу несколько микросервисов, внимание распыляется. Он может забыть или не успеть сделать тест, что-то пропустить. Поэтому мы пришли к выводу, что оптимальные соотношения это:

  • 1 разработчик — один активный микросервис;
  • 1 разработчик — 3 пассивных микросервиса, которые он знает.

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

Стабильность микросервисов

Если следовать рекомендациям по созданию микросервисной архитектуры, у вас должно быть много серверов. Например: eсть микросервис 1 и микросервис 2. На каждый тип или группу микросервисов должен быть балансер, а на каждую группу микросервисов должна быть своя база данных в режиме master-slave. И выходит так, что на каждую группу мы должны выделить от 5 серверов для того, чтобы добиться максимальной отказоустойчивости. Если у вас 20 микросервисов, теоретически должно быть более 100 серверов. Это если мы говорим о своем железе.

У нас было 3 мощных сервера, на которых находились все наши микросервисы. В работе с микросервисами лучше иметь много мелких, чем несколько мощных серверов. Высоконагруженные микросервисы мы выносим на отдельные, более мелкие сервера. В результате мы поняли, что это большой перенапряг по обслуживанию и мониторингу. На сегодняшний день мы перешли на Kubernetes. В процессе перехода и работы нам пришлось попотеть. Результаты хорошие. Нужно инвестировать много ресурсов, но оно того стоит. Нужно отметить, что сервера с базами данных живут отдельно.

Существует мнение, что микросервисы — это мегастабильные системы. Я могу сказать, что стабильность у микросервисов действительно высокая. Когда мы запускались, у проектов были проблемы со стабильностью. Но если вы все правильно делаете с самого начала, в результате у вас будет очень стабильное приложение. Для этого нужно следовать подходу, который говорит, что все микросервисы могут падать и не отвечать. Для того чтобы проверить, правильно ли написаны микросервисы, вы должны отключать микросервисы и смотреть, как другие работают без них. Чтобы они умели нормально работать и имели сценарии на тот случай, если один из них упадет или не ответит. Вот когда вы все эти комбинации попробуете, вручную или автоматом, тогда эта система будет работать мегастабильно.

Выводы

Важные моменты при переходе на микросервисы:

  • микропроблемы лучше, чем большие проблемы на монолите;
  • контейнеризация и автотесты — must have;
  • легкое масштабирование как проекта, так и команды;
  • легкость в интеграции новых технологий;
  • плавная миграция с монолита лучше, чем force;
  • мощная и продвинутая система мониторинга;
  • хороший системный администратор или DevOps;
  • отдельная тема — это контейнеризация, которая будет раскрыта в отдельной статье. Но если коротко сказать, то использование Kubernetes + Docker + GitLab CI выводит управление и мониторинг микросервисов на другой уровень.

Микросервисы — это идеальная экосистема для экспериментов:

  • переписывать весь проект не нужно, благодаря консультациям мы за год не переписывали ни один микросервис полностью;
  • Fast CI — быстрый CI помог нам избавиться от многих проблем;
  • новый функционал появляется быстрее, чем его могут протестить;
  • обратная совместимость всех частей приложения: вы всегда можете откатиться до предыдущей версии и делать тестирование на старой или новой версии;
  • возможность масштабирования;
  • низкая стоимость ошибки — даже если джуниоры что-то испортили, любой микросервис можно переписать в течение 1-3 дней.

«Распределенный монолит»

Недавно я был на ивенте PHP Friends meetup #4 (Tech Leads Panel), на котором я очередной раз рассказывал о нашем опыте и микросервисах. Я познакомился с Максимом Волошиным из OWOX (очень техничный и опытный специалист) и услышал от него фразу «распределенный монолит» — это дало пищу для размышлений. Так как у нас разнообразные микросервисы — некоторые абсолютно самостоятельные, а некоторые плотно завязаны на другие микросервисы — у меня появилось ощущение, что 2 наших микросервиса (User и Catalog) можно справедливо отнести к распределенному монолиту.

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

У меня в голове выработалось правило: если ты денормализируешь данные с другого сервиса с данными твоего микросервиса, то у тебя не микросервис. Его можно по-разному называть: сервис, распределенный монолит, самодостаточное приложение и т. д. Скользкая приставка «микро» дает много поводов к спорам по поводу трактовки. Из-за этого могу с чистой совестью сказать, что за последние 2 года, общаясь с разными ребятами, которые работают или работали с микросервисами, я увидел, что реализации настолько отличаются друг от друга, что кажется что под словом «микросервис» пытаются преподнести все, что не есть монолит.

У меня есть рекомендация — мигрировать постепенно и выводить в микросервис то, что не имеет зависимостей от других микросервисов или монолита (как функционально, так и на уровне данных). Тогда у вас появится понимание и опыт, после чего вы начнете видеть тонкую грань между микросервисом и всем остальным.

LinkedIn

48 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

Как вы работаете с транзакциями ? Они всегда происходят только в одной базе или есть транзакции на уровне приложения ?

Вопрос не ко мне, конечно, но самый правильный ответ — Don’t. Стоит проектировать систему таким образом, чтобы данные, которые нужно изменить жили внутри сервиса. А изменения публиковать через сообщения (события). Ключевые слова AggregateRoot, Event-Driven Architecture, Saga.

Зачем изобретать велосипед, когда есть Spring Boot, Spring Cloud с интеграцией продуктов Netflix. Тут вам и Zuul в качестве фронтенда, и Eureka/Ribbon для баланса нагрузки, и Hystrix/Turbine для обработки таймаутов и их трекинга? Причем совершенно бесплатно

А что вы делали с моделью данных?

Например, Users и у них есть свой микросервис
и соответсвенно для Products и Orders.

Проблема в том что логика в сервисе Orders требуется знание о Users и Products.
Использовать одну большую модель данных для всех противоречит идее то что это микро.
Либо у каждого микросервиса своя модель данных, и получается которая во многом повторение того что у других.

Это можно решить через bounded context

Какая-то статья только для специалистов по микросервисам от специалиста по микросервисам. Куча незнакомых терминов и странных решений. Вообще не описано зачем такой секс с базами данных(сначала все обьединяем, потом делим по новому, ну прямо комунизм).

это связано с тем чтобы разрешить все проблемы со связями. Во время объединения 7 БД в одну все данные получают новые ID, тем самым убираем проблему с пересекающими ID. User ID =1 в семи странах это 7 разных пользователей. У каждого с ним есть много связанных других сущностей.

Как организовали процесс деливери и управление всем зоопарком, в разрезе используемых инструментов

Деливери — хороший вопрос. Каждый микросервис релизится самостоятельно и когда например задача выполнена. Есть сложные релизы когда нужно релизить много сразу микросервисов но тогда мы указываем план выкатки. То есть зависимые микросервисы от других выкатываются последними.
Скажу вот еще. Если регулярно релизить то проблем нету — в основном проблемы если накапливаются много фич новых на микросервисе и его потом выкатываешь. У нас в неделю от 3 до 20 релизов в неделю.

Кстати, у вас монорепа или отдельная репа на каждый сервис?

Каждый микросервис отдельный репозиторий, отдельная документация, свой pipeline в GitLab CI.

InfluxDB+Grafana
Zabbix

А ведь можно было поставить один Prometheus.

Да — сейчас мы работаем над ним.

InfluxDB+Grafana

это для KPI и бизнес метрик которые девелоперы пишут. Например количество ушедших писем, или количество опубликованных объявлений. После релиза можно зайти и посмотреть как в реал тайме работают Бизнес Процессы.

Zabbix

 — это наследство от нашего железа — по правде говоря у нас еще оно и осталось, когда проблемы на кубе мы сразу весь трафик бросаем на старую инфраструктуру. Мы ее держим пока полностью не отполируем куб. Очень мало экспертизы в нем.

Не пойняв — у вас 7 різних баз даних з РІЗНОЮ структурою ? Якщо так, то тут не мікросервіси треба, а щось в консерваторії міняти.
Якщо структура однакова, все це можна змігрувати в одну базу даних з REGION_ID, USER_ID.
Потім вже (за бажанням) об’єднувати дані по де-факто однаковим юзерам.
Нахрена потім знову все розносити по різним базам — не зрозумів.

P.S.
Склалося враження, що перехід на мікросервіси в даному випадку скоріше бажання щось нове попробувати, ніж необхідність. :)

Было 7 бд под каждую страну. То есть монолит сетапился под каждую страну. Сейчас мы разнесли по принципу не региональной принадлежности а по принципу микросервисов что смогли и некоторые превратились в полноценные сервисы.

а как вы сейчас шардинг делаете?

так как разбили все на мелкие микросервисы то он не нужен. Хотя рано или поздно придется какой то микросервис шардировать но это до 10 таблиц.

а не смотрели на multitenant?

А тестируете ли контракты между микросервисами?
Тоесть например ситуация, когда микросервис А потребляет API микросервиса Б.
Мы меняем метод у микросервиса Б, но забываем за микросервис А.

Как вы узнаете о поломке?

у нас все версионное, то есть если мы меняем ответ (сужаем или полностью изменяем схему) это новый эндпоинт или новая версия АПИ. + Все эндпоинты покрыты тестами.

Спасибо!
Еще вопрос, а фронтенд на микросервисы не разделяли? Или клиент монолитен?

Клиент у нас почти логики не содержит он отвечает сходить на микросервисы, агрегировать данных, и отображать их.

Версионирование endpoint-ов не всегда благодарный подход. Иногда легче использовать forward/backward compatibility & significant defaults

Вот тут dzone.com/...​ntainerised-microservices описал процесс одного из проектов

но на фронт-микросервис приходилось слишком много трафика. Поэтому возникло желание его переписать. У нас он написан на PHP, оптимально было бы перейти на Rust или Go, чтобы он работал быстрее. Хотя на тот момент проблем с производительностью не было, прежде чем переписывать его мы подумали, а может есть какой-то другой вариант?

поставить перед ним LB? )

Вопрос в скорости а не в обработке трафика. В теории можно и на React PHP, суть в том что фронт контроллер получает запрос, потом идем на юзер микросервис для верификация токена. Потом идем на сам микросервис за данными, потом возможно мы эти данные хотим перевести на другой язык, то есть сходить на микросервис переводов и взять переводы для определенного языка для определенной категории, потом все это собрать ответ и выплюнуть клиенту. Если сделать все это параллельно то в сложных запросах это в 10 раз прирост. На чистом PHP выглядит не совсем рациональным.

потом идем на юзер микросервис
Потом идем на сам микросервис за данными
потом возможно мы эти данные хотим перевести на другой язык
потом все это собрать ответ и выплюнуть клиенту

Так какие операции из этой цепочки можно выполнить параллельно?

сразу все операции. А потом когда все выполнятся принять решение, имеет доступ или нет если да то выплевываем то что собрали.

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

Запросы когда прав доступа нету это меньше 0.1% от всех запросов. Для того чтобы перевод сделать нужно сначала их получить у микросервиса переводов. Их можно положить локально или в кеш но тогда начнутся пляски с инвалидации данных.
То есть всю коммуникацию выносим в параллельное выполнение а потом оперируем с результатоми.

У вас там действительно что-то типа гугл транслейта в микросервисе или вы так просто локализацию сделали?

Сховище даних в вас мікросервіс чи ні?

не совсем понял. Микросервисы у нас с БД и без БД — есть которые хранят данные, есть которые только что то выполняют. Есть которые пишут, а есть которые только читают и агрегируют.

у вас там с кубером были какие-то проблемы. побороли их?

проблем было много и есть еще. Провал в перфоменсе но это было связано с тем что наши БД были далеко + проблема в открытие коннекшена. Первая решается тем что перемещать по ближе но при этом есть нюанс чтобы на нашем железе параллельном тоже БД была рядом. Вторая проблема решается поднятием внутри куба Pgbouncer. Еще одна проблема которая есть — отпадает сетка внутри после обновления куба. Думаю в ближайшие дни решим это.

Є декілька схем побудови мікросервісної архітектури. Одна з них — розділення на сервіси за утилітарною ознакою, а не за бізнес-призначенням або функціональною. Тобто сховище даних буде мікросервісом для інших сервісів.

Это, мягко говоря, не лучший подход. БД сама по себе есть сервис, зачем на ней еще один сервис прикручивать?

Блін, тільки побачив, що не на той комент дав відповідь. Але ладно, продовжимо вже тут.
Сервіс над БД необхідний для того, щоб абстрагуватися від сруктури та способів збереження/читання даних. Якщо вам захочеться використовувати дві таблиці замість однієї, або перейти на документний підхід замість реляційного, або взагалі змінити СУБД на іншу, ніхто назовні це не побачить.

В итоге у вас получится монолит из микросервисов так как каждый сервис будет знать о сервисе доступа к данным со всеми вытекающими. Абстракции над БД стоит делать в адапторе доступа к данным внутри самого сервиса. Эту статью можно почитать blog.christianposta.com/...​about-microservices-data.

Щось я не дуже збагнув, чому саме моноліт вийде, якщо ідея як раз навпаки, ще більше від’єднати бізнес-логіку від збереження даних.

Абстракции над БД стоит делать в адапторе доступа к данным внутри самого сервиса

Так звісно ж легше, але підтримка цього варіанту вимагає версійності мікросервіса навіть при мінімальних змінах в процесі роботи з даними.

Щось я не дуже збагнув, чому саме моноліт вийде

Читал статью, которую я приводил? Монолит получится потому что все сервисы будут говорить с одним/несколькими сервисами бд, будут от них зависить.

підтримка цього варіанту вимагає версійності мікросервіса

Зачем? Каждый сервис имеет своию схему данных. Хранится она с одной бд или разных не имеет особого значения. Еще раз, зачем?

Монолит получится потому что все сервисы будут говорить с одним/несколькими сервисами бд, будут от них зависить.

Так вони й так від них залежать. Тільки це вписано в код сервіса.

Каждый сервис имеет своию схему данных.

Зазвичай так й будують. Невід’ємна пов’язаність даних та способів їх обробки. Але, якщо розкласти будь-який мікросервіс на запчастини по процедурній ознаці, то вони майже всі будуть виконувати однакові процедури. Давай подивимося, наприклад, на систему підписання документу. В нас, припустимо, є декілька учасників процесу: клієнти, внутрішні працівники, внутрішня система автоматичного підписання, система зовнішнього підписання. Зазвичай будують систему, в якій різні сервіси будуть в собі мати власну реалізацію процедури підписання. Хоча процедуру підписання можна винести в окремий мікросервіс, який буде займатися виключно цим процесом.

це вписано в код сервіса.

А не его контракт, чувствуешь разницу?

Хз что ты хотел показать своим примером. Откуда это «зазвичай», разве это общеизвестный факт?

Сервисы стоит выделять согласно поддоменам (Bounded Contexts), когда границы уже устаканились и всем понятны. БД тут вообще ни при чем.

Підтримую, + не рекомендую ділити сервіси «а вдруг захочеться абстрагуватись», якщо дуже захочеться, тоді вже можна і ділити, а то там можна 10 слоїв всюди де можна натягнути і розбирайся потім з цим.

Щось я не дуже збагнув, чому саме моноліт вийде, якщо ідея як раз навпаки, ще більше від’єднати бізнес-логіку від збереження даних.

То о чем вы говорите это дизайн уровня сервиса и его внутренней реализации, а микросервис/монолит закладывает принципы на уровне взаимоедйствия подсистем, а не способ их внутренней реализации. Говоря проще, даже если в вашем приложении бл и дал разделены, если дал отвалиться — все приложение будет неработоспособным, поэтому это монолит.

Подписаться на комментарии