Deadline.by
Deadline.by

Опишите задачу — посчитаем смету и сроки за день

реальный проект

Платформа на микросервисах с мини-приложением

Проект показываем обезличенно: без названия, отрасли и ссылок

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

Кейс — Платформа на микросервисах с мини-приложением
FastAPI · PythonNestJS · PrismaШлюз с проверкой токенаKafka · Redis · PostgreSQLReact · Vite · Mini App

Задача

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

Что сделали

  • Выделение сервисов по областям, а не по слоям: авторизация, профили, основная логика, работа со второй сетью
  • Единый шлюз: проверка токена выполняется на уровне веб-сервера, до того как запрос дойдёт до сервиса
  • Очередь событий между сервисами — обмен переживает недоступность получателя без потерь
  • Своё хранилище у каждого сервиса вместо общей схемы на всех
  • Мини-приложение как основной интерфейс пользователя, с авторизацией через платформу мессенджера
  • Сквозная трассировка запроса и сбор метрик до переноса боевой нагрузки
  • Миграции и раздельная выкладка: сервис обновляется без остановки остальных

Результат

  • Сервисы обновляются независимо, правка одного не требует выкладки остальных
  • Проверка доступа вынесена в одну точку — сервисы не дублируют логику авторизации
  • Вторая блокчейн-сеть добавлена отдельным сервисом, без переписывания существующего кода
  • Сбой одного сервиса не роняет платформу целиком: обмен ждёт в очереди

Где мы провели границы между сервисами

Самая частая ошибка при разделении — резать по слоям: отдельно работа с базой, отдельно бизнес-логика, отдельно интерфейс. В такой схеме любая новая функция требует правки во всех трёх сервисах и согласованной выкладки, то есть ровно того, ради избавления от чего разделение и затевалось. Мы резали по областям: авторизация целиком, профили целиком, основная логика целиком.

Проверка простая: если типовая задача закрывается изменением в одном сервисе — граница проведена верно. Если задевает три — граница проведена по слоям, и её нужно передвигать, пока это ещё дёшево.

Почему проверка токена ушла на уровень веб-сервера

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

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

Очередь вместо цепочки вызовов

Синхронная цепочка, где сервис вызывает второй, тот третий, а третий четвёртый, недоступна, если недоступно любое звено. То есть надёжность разделённой системы получается хуже, чем у монолита, — при том, что за разделение уже заплачено. Поэтому всё, что не требует мгновенного ответа, идёт через очередь: инициатор получает подтверждение приёма, а результат приходит позже.

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

Что мы настроили до того, как перенесли нагрузку

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

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

Заполнить бриф