ADG Оставить заявку
Блог DevOps 2 мин чтения

Микросервисы на практике: Docker + Swarm + Nginx вместо монолита

Первый клиент попросил разбить монолит на сервисы. Взяли Docker Swarm и Nginx как API gateway. Главный вызов оказался не в технике, а в том, кто за что отвечает.

Контекст момента

Микросервисная архитектура становится доминирующим паттерном для новых проектов в 2015 году

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

Что было у клиента

PHP-монолит, которому лет шесть. Несколько сотен тысяч строк. Всё в одном репозитории: веб-интерфейс, API для мобильного приложения, фоновая обработка очередей, генерация отчётов, интеграции с внешними системами. Деплой - scp и перезапуск Apache. Любое изменение в модуле отчётов может случайно сломать API, и всё это обнаруживается уже после деплоя.

Запрос клиента был честный: не «мы хотим микросервисы потому что так правильно», а «мы больше не можем деплоить без страха». Это понятная инженерная боль, с которой можно работать.

Какой стек выбрали и почему

Kubernetes мы к этому моменту уже смотрели - и в тестах, и в свежем опыте с overlay-сетями в Swarm. Вывод был такой: для этого проекта Kubernetes избыточен. Команда у клиента небольшая, инфраструктурной экспертизы мало, а K8s требует выделенного внимания на поддержку самого кластера - etcd, scheduler, controller-manager, сеть. Это отдельный проект внутри проекта.

Взяли Docker Swarm - с тем самым опытом, который у нас был с сентября. Поверх - Nginx как API gateway: он принимает запросы снаружи и роутит к нужному сервису по префиксу URL. Схема выглядит примерно так:

  Клиент (браузер / мобилка)
         |
       Nginx  <-- API gateway, SSL termination
      /  |  \
   /    |    \
svc-api  svc-reports  svc-worker
  (Swarm)    (Swarm)     (Swarm)

Простая конфигурация Nginx:

location /api/ {
    proxy_pass http://svc-api:8080/;
}
location /reports/ {
    proxy_pass http://svc-reports:8080/;
}

Каждый сервис - отдельный Docker-образ, отдельный репозиторий, отдельный CI-пайплайн. Деплоим через docker-compose pull && docker-compose up -d - только тот сервис, который изменился.

Технически всё завелось. Дальше началось интересное

Технических проблем было ожно и они решались. Shared база данных - главная из них: монолит работал с одной PostgreSQL, и дать каждому сервису свою схему можно было только поэтапно. Мы начали с логического разделения: сначала разные схемы в одной БД, с договорённостью что сервисы не ходят в чужие таблицы напрямую. Это костыль, но управляемый.

Настоящая проблема оказалась организационной. Монолит - он один, и понятно кто за него отвечает: вся команда разработки. Когда появились три сервиса - возник вопрос, который никто заранее не обсудил: кто владеет каждым сервисом?

На практике это выглядело так:

  • Баг в svc-reports. Разработчик, который его дорабатывал, ушёл в отпуск. Кто правит? Непонятно.
  • Нужно изменить контракт API между svc-api и svc-reports. Кто принимает решение? Обе стороны говорят «мне так неудобно», и обе правы.
  • Кто следит за тем, что svc-worker не упал? «Это инфраструктура» - говорит разработка. «Это приложение» - говорим мы.

Без ответа на эти вопросы микросервисная архитектура создаёт не меньше боли, чем монолит, а больше - только распределённой.

Мы в итоге помогли клиенту написать простую матрицу ответственности: у каждого сервиса есть владелец (конкретный человек или пара), он же участвует в ревью всех изменений в этом сервисе, он же дежурит по нему. Звучит как очевидная практика - но до явного разговора это висело в воздухе.

Что получилось к декабрю

Три сервиса работают в Swarm, остальная часть монолита пока живёт как есть. Деплой стал независимым - можно выкатить только API без риска задеть очереди. Nginx справляется как gateway без каких-то специальных инструментов.

Kubernetes в этом сценарии был бы лишним. Swarm с текущей командой - управляемо. Может, через несколько месяцев появится потребность в чём-то что Swarm не умеет - посмотрим. Пока справляемся.

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

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.