Привет, я разработчик программного обеспечения в компании 1221Systems и хочу рассказать об опыте перевода проекта с монолитной архитектуры на микросервисную: как выглядел исходный проект и с какими проблемами мы столкнулись, какую архитектуру построили после рефакторинга и какие преимущества в итоге получили.

Что у нас было

Проект состоял из двух частей:

  • Монолит на PHP / JS / PostgreSQL

    • Интерфейс управления рекомендациями

    • Логика хранения и отображения данных

  • ML-сервис на Python

    • Прогнозирование поведения пользователей

    • Формирование рекомендаций

Исходная система работала стабильно, но со временем начались проблемы. Визуально ее можно представить так:

Почему решили переделать

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

  • Разнородность технологий без четкого разделения ответственности: PHP и Python использовались совместно, но без границ между компонентами.

  • Проект разрастался, появлялись новые функциональные элементы и компоненты, что могло привести в данной архитектуре если не к краху, то к большим проблемам.

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

Что у нас получилось

После рефакторинга архитектура стала выглядеть так: 

После декомпозиции мы разделили систему на четыре микросервиса:

1. Сервис приема данных

  • Что делает сервис: принимает информацию для хранения и обработки

  • Стек: Python / PostgreSQL

2. Административный сервис

  • Что делает сервис: управление настройками рекомендаций, для дальнейшего просчета

  • Стек: JS / Symfony / PostgreSQL

3. Сервис просчета рекомендаций

  • Что делает сервис: обучение моделей, прогнозирование, формирование рекомендательных лент

  • Стек: Python (scikit-learn, PyTorch)

  • Особенности: вычислительно тяжелый, легко масштабируется горизонтально

4. Сервис отдачи рекомендаций

  • Что делает сервис: предоставление готовых лент рекомендаций

  • Стек: Symfony / Redis / gRPC

Что нам потребовалось?

Для надежной работы всех микросервисов мы внедрили такую инфраструктуру:

  • API Gateway – маршрутизация запросов, аутентификация, ограничение скорости

  • Шина сообщений – Kafka / RabbitMQ для асинхронного взаимодействия

  • Контейнеризация – Docker + Kubernetes для автоматического деплоя и масштабирования

  • Логирование и мониторинг – Prometheus, Grafana

Какие трудности?

  • Сложности взаимодействия команд на разных стеках: нужно документировать API и стандартизировать взаимодействие ни только между сервисами, но и между командами

  • Управленческая сложность: управление множеством сервисов требует хорошего DevOps-обеспечения. Кроме того, возникла проблема управления большим количеством разносторонних сервисов с различной архитектурой и стеком.

  • Согласованность данных: проблема при синхронизации больших объемов данных. Пришлось распределять данные по различным хранилищам (postgreSql, ElasticSearch). Распределенные данные потребовали применения паттернов Event Sourcing или Saga.

В итоге мы получили такие плюсы

  • Независимость сервисов

    • Тестирование, обслуживание и обновления стали проще

    • Быстрее вывод новых фич

  • Гибкость в выборе технологий

    • Можно использовать оптимальный стек под каждую задачу

  • Масштабируемость

    • Каждый сервис можно масштабировать отдельно

  • Высокая отказоустойчивость

    • Выход одного сервиса не парализует всю систему

  • Поддержка экспериментов

    • Возможность A/B-тестирования на уровне отдельных сервисов

Итого

Переход на микросервисную архитектуру — это не только технический, но и организационный процесс. Он требует планирования, стратегии и понимания целей, вовлеченности всей команды (спасибо коллегам!), и нужно быть готовыми к этому. Зато этот шаг открывает широкие возможности для масштабирования, гибкости и развития продукта (об этом – в следующей статье).

Разделение исходного монолита на микросервисы позволило значительно повысить производительность, отказоустойчивость и скорость разработки. Это стало важным этапом в развитии нашей рекомендательной системы и дало возможность эффективно разрабатывать новые функции для бизнеса. Если у вас был аналогичный опыт, было бы интересно обсудить его в комментариях!

Комментарии (8)


  1. namee
    05.08.2025 05:29

    Нехватает продолжения в виде "и в итоге очень пожалели"

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


  1. ivankudryavtsev
    05.08.2025 05:29

    Через год можно писать «как мы перешли с микросервисов на монолит».


  1. 2medic
    05.08.2025 05:29

    Изменения в одном модуле могли повлиять на другую часть

    Так всё-таки — могли или реально влияли?

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

    И ещё интересно: в чём именно была сложность полного тестирования системы? Это больше про объём работы, отсутствие автоматизации или про организационные ограничения?


    1. sayutin_v Автор
      05.08.2025 05:29

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


  1. tkutru
    05.08.2025 05:29

    Как это обычно бывает, микросервисная-на-словах архитектура стала просто сервисной (SOA).

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

    А всё потому, что кто-то где-то услышал, что (микро)сервисная архитектура - это стильно, модно, молодёжно.


  1. roxblnfk
    05.08.2025 05:29

    Вообще не вижу ничего плохого в том, что распилили на сервисы. Даже поддержал бы в том, что разным стекам место в разных репозиториях. Контракты на gRPC -- окей. Документированное API -- ну а как иначе? Нужен девопс -- куда-ж без него, когда ещё надо и горизонтально масштабироваться?

    В принципе всё логично. Но сухо: "было так, решили, переделали, стало сяк. Вот очевидные плюсы и очевидные минусы". А где мясо?

    • Какие были сложности и внезапные приколдесы при рефакторинге?

    • Что рассматривали и в итоге взяли для gRPC сервера на пыхе с симфой?

    • Смотрели ли на Temporal? Почему не взяли?

    • Смотрели ли на OTEL и трейсинг в целом?

    • Какие ошибки допустили и какие советы могли бы дать, чтобы это избежали другие?


    1. 2medic
      05.08.2025 05:29

      Вообще не вижу ничего плохого в том, что распилили на сервисы

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

      Надо начинать с вопросов: действительно ли есть проблемы, которые решают микросервисы? Готовы ли разработчики к многократному усложнению инфраструктуры? Осилит ли команда поддержку такой системы?

      Если ответы — нет, возможно, переходить на микросервисы преждевременно.

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

      Segment — переход назад к монолиту (Goodbye Microservices: From 100s of problem children to 1 superstar)

      Hey.com / Basecamp — возврат к монолиту. DHH (David Heinemeier Hansson) про возврат к монолиту («Не буду отрицать, что существуют случаи, когда архитектура, ориентированная на микросервисы, имеет смысл, но, думаю, их мало. Подавляющему большинству систем гораздо выгоднее начинать и поддерживать величественный монолит.») Рассуждения и рекомендации, почему вернулись и не стоит дробить систему.

      Monzo — не то, чтобы вернулись, но признали проблемы и развернулись в сторону централизации.


      1. roxblnfk
        05.08.2025 05:29

        Надо начинать с вопросов: действительно ли есть проблемы, которые решают микросервисы? Готовы ли разработчики к многократному усложнению инфраструктуры? Осилит ли команда поддержку такой системы?

        Я рассуждаю так: если уже распилено, значит причины (проблемы) были. Раз решились, значит о рисках знали и их приняли (или не знали, но готовы были встретить). В общем статья то и не о муках принятия решения, а конкретно о переходе.

        Я работал с микросервисами и чувствовал себя прекрасно; и как какой-то сервис слишком набухал, его дробили. Да, можно писать весь проект в одной репе и размазывать его полностью или частично по подам, называя это распределённым монолитом. Но будем честны: у монолитов тоже хватает проблем.