БесплатноБесплатный прототип ключевой страницы и черновик ТЗ при старте проекта

Микросервисы вокруг 1С-Битрикс: когда и как

Микросервисы вокруг 1С-Битрикс: монолит портала и вынесенные рядом сервисы, обмен по REST и через очередь

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

Ниже — практический разбор: когда вынос действительно оправдан, а когда только добавит боли; как проводить границы между монолитом и сервисами; чем обмениваться (REST, вебхуки, очереди) и как не потерять и не задвоить данные. Это выжимка из наших проектов по разработке и доработке на 1С-Битрикс — без модных слов ради модных слов, с оглядкой на реальную эксплуатацию.

Коротко

  • Микросервис оправдан там, где логика тяжёлая, автономная или чужеродная для PHP-монолита: расчёты, интеграции с внешними SLA, специфичные технологии, отдельная нагрузка.
  • Битрикс остаётся ядром — витрина, каталог, заказы; сервисы живут рядом и общаются с ним только через API и события, а не через общую базу.
  • Синхронный REST — когда ответ нужен пользователю сразу; очередь — когда операция долгая или должна пережить недоступность получателя.
  • Надёжность строится на трёх китах: outbox, доставка «хотя бы один раз» с повторами и идемпотентная обработка по устойчивому ключу.
  • Начинайте с монолита и выносите сервисы точечно под конкретную боль, а не «на всякий случай».

Зачем вообще выносить логику из Битрикса

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

Классические симптомы, что задача «переросла» монолит, выглядят так:

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

Важно: микросервис не делает систему автоматически «лучше» — он меняет один набор проблем (сложность внутри монолита) на другой (сложность распределённой системы: сеть, согласованность, наблюдаемость). Выигрыш есть только тогда, когда новый набор проблем для вашей задачи дешевле старого.

Когда микросервис оправдан, а когда нет

Прежде чем писать первый сервис, честно ответьте на вопрос: а нельзя ли решить задачу внутри Битрикса? Очень часто можно — агентом, обработчиком события, отдельным модулем на D7, фоновым скриптом по cron. Микросервис оправдан, только когда штатных средств действительно не хватает. Ниже — ориентир по типовым ситуациям.

СитуацияМикросервисПочему
Тяжёлый расчёт, блокирующий страницуДаВыносим из hit, отвечаем асинхронно, не упираемся в таймауты
Интеграция с внешним API со своим SLAДаСервис-адаптер инкапсулирует лимиты, ретраи и деградацию
ML/парсинг/обработка медиаДаНужна не-PHP технология и отдельное масштабирование
Пиковая нагрузка на отдельную функциюДаМасштабируем сервис независимо от витрины
Простой расчёт скидки или бонусаНетДешевле обработчиком события внутри Битрикса
Периодическая выгрузка в файлСкорее нетДостаточно агента или cron-скрипта
Небольшой магазин, маленькая командаНетЭксплуатация распределёнки дороже, чем выигрыш

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

Тест на необходимость: если вы не можете назвать конкретную боль (метрику, инцидент, ограничение), которую снимет вынос, — сервис вам пока не нужен. «Чтобы было масштабируемо» и «чтобы модно» болью не считаются.

Как проводить границы: что остаётся в монолите

Самая частая ошибка при переходе к сервисам — резать систему по техническим слоям («сервис базы», «сервис уведомлений»), а не по бизнес-возможностям. Правильная граница проходит вокруг связной части предметной области, которая меняется вместе и имеет собственные данные. Такой кусок можно развивать и деплоить независимо, и именно это — цель.

Практический ориентир, что оставить в ядре Битрикса, а что можно вынести:

Хороший признак правильной границы — минимальный и стабильный контракт на стыке. Если сервису для работы постоянно нужно лазить в десяток таблиц Битрикса и знать его внутреннее устройство, граница проведена неудачно: связность не уменьшилась, а спряталась в сеть, где отлаживать её ещё сложнее. Стремитесь к тому, чтобы через границу проходил узкий, осмысленный набор команд и событий на языке бизнеса, а не «дай мне строку из b_iblock_element».

Ядро 1С-Битрикс витрина · каталог · заказы Расчёт доставки сервис-адаптер Рекомендации ML, своя нагрузка Документы PDF, акты, счета ERP-адаптер 1С, маркетплейсы
Схема: Битрикс остаётся ядром покупки, а тяжёлые и чужеродные функции живут вокруг как отдельные сервисы с узким контрактом.

Топология: Битрикс как ядро и сервисы вокруг

Не стоит представлять микросервисы как «россыпь равных сервисов вместо монолита». В связке с Битрикс почти всегда работает более прагматичная топология: монолит остаётся ядром и «источником правды» по заказам и каталогу, а сервисы прирастают по краям, решая отдельные задачи. Это часто называют «микросервисы вокруг монолита» — и для e-commerce на Битрикс это здоровая модель.

В такой топологии полезно выделить несколько ролей:

Важный вопрос — кто оркеструет процесс. Пока сервисов немного, роль дирижёра спокойно берёт на себя Битрикс: он вызывает сервисы в нужном порядке и собирает результат. Когда процессов и участников становится много, оркестрацию (жёсткий сценарий «сделай А, потом Б») постепенно заменяют хореографией (участники реагируют на события и сами знают, что делать дальше). Для большинства магазинов на Битрикс до хореографии дело не доходит — и это нормально.

Если вы двигаетесь в сторону разделения фронтенда и бэкенда, топология сервисов хорошо ложится на подход headless-коммерции на Битрикс: витрина-фронтенд общается с ядром и сервисами через API, а не через готовые компоненты.

Способы обмена: REST, вебхуки и очереди

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

МеханизмКогда применятьРиски
Синхронный REST (Битрикс → сервис)Ответ нужен пользователю сразу, операция быстрая и предсказуемаяТаймауты и падение сервиса блокируют страницу
Вебхук (сервис → Битрикс)Сервис сообщает о готовности результата или внешнем событииНужна проверка подписи и защита эндпоинта
Очередь / брокер сообщенийОперация долгая, может подождать, должна пережить недоступностьСложнее отлаживать, нужна идемпотентность

В экосистеме Битрикс входящий и исходящий обмен по REST — это уже привычная история: входящие и исходящие вебхуки, OAuth-приложения, батч-запросы. Механику самого REST мы подробно разбирали в материале REST API в 1С-Битрикс — там про вебхуки, лимиты и группы методов. Здесь важно другое: не делайте синхронный внешний вызов прямо в hit пользователя без страховки. Один медленный ответ службы доставки — и оформление заказа висит пять секунд, а при недоступности сервиса вообще падает.

Важно: любой синхронный вызов внешнего сервиса из hit оборачивайте в таймаут и предусматривайте деградацию. Не смог рассчитать точную доставку за 800 мс — покажите базовый тариф и досчитайте асинхронно. Пользователь должен иметь возможность оформить заказ, даже когда сервис-адаптер недоступен.
Синхронно (REST) Асинхронно (очередь) Битрикс Сервис Битрикс Очередь Сервис ждём ответ ⏳ не ждём ✓
Схема: синхронный REST держит пользователя в ожидании ответа сервиса, очередь принимает команду мгновенно и выполняет работу в фоне.

Очереди и события: асинхронный контур

Как только появляется операция, которую можно не выполнять прямо сейчас, на сцену выходит очередь — брокер сообщений (RabbitMQ, Kafka, Redis Streams и им подобные). Битрикс кладёт в очередь сообщение «нужно сделать то-то», отдаёт управление пользователю, а сервис-обработчик забирает сообщение и делает работу в своём ритме. Это развязывает отправителя и получателя во времени: они больше не обязаны быть доступны одновременно.

Асинхронный контур решает сразу несколько задач:

Здесь важно развести два понятия. Команда — это «сделай Х» (посчитай доставку, сформируй документ), у неё один адресат. Событие — это «произошло Y» (заказ оплачен, статус изменён), у него может быть много подписчиков, каждый реагирует по-своему. События — основа слабой связанности: ядро публикует «заказ оплачен», а кто на это подпишется (уведомления, бонусы, аналитика, ERP), ядру знать не обязательно.

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

Важно: очередь не «ускоряет» операцию — она переносит её во времени и делает необязательной прямо сейчас. Если пользователю нужен результат немедленно (цена, наличие), очередь не подходит: тут либо быстрый синхронный вызов, либо заранее посчитанные данные.

Идемпотентность, outbox и надёжная доставка

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

Надёжный обмен строится на трёх приёмах, которые работают только вместе:

  1. Outbox (журнал исходящих). Событие записывается в свою таблицу в той же транзакции, что и бизнес-изменение. Либо и заказ, и запись «заказ создан» сохранятся вместе, либо не сохранится ничего. Отдельный отправитель потом читает журнал и публикует события в очередь. Так исключается ситуация «данные записаны, а событие потеряно».
  2. Доставка «хотя бы один раз». Отправитель повторяет попытку, пока брокер не подтвердит приём; обработчик подтверждает сообщение только после успешной обработки. Это гарантирует, что сообщение дойдёт, но ценой возможных дублей — их снимает следующий пункт.
  3. Идемпотентная обработка. У каждого события есть устойчивый уникальный ключ (например, идентификатор события или бизнес-операции). Получатель хранит обработанные ключи и, встретив повтор, просто игнорирует его. Повторная доставка не создаёт второй заказ и не начисляет бонус дважды.

Дополняют картину две вещи. Dead letter queue (очередь «мёртвых» сообщений) — куда уходят сообщения, которые не удалось обработать после N попыток; их разбирают вручную или отдельным процессом, не блокируя основную очередь. И backoff — растущие паузы между повторами, чтобы не долбить упавший сервис и дать ему восстановиться.

Транзакция заказ + outbox в одном коммите Outbox → отправитель Очередь ≥ 1 доставка Обработчик ключ уже был? да → игнор ✓ повтор при сбое (backoff)
Схема: outbox гарантирует запись события вместе с заказом, очередь доставляет «хотя бы один раз», а идемпотентный обработчик по ключу отсекает дубли.

Данные: у каждого сервиса своя база

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

Почему общая база данных ломает границы:

Правильно — обмениваться через API и события, а данные держать у себя. Если сервису для работы нужна часть данных Битрикса (например, справочник товаров), он получает их через API и хранит свою рабочую копию (проекцию), которую обновляет по событиям. Да, это означает, что одни и те же данные живут в двух местах и согласуются не мгновенно, — но это осознанная плата за независимость, и для большинства сценариев «согласованность в конечном счёте» полностью устраивает бизнес.

Важно: «своя база у сервиса» не означает обязательно отдельный сервер СУБД. На старте это может быть отдельная схема/база на том же инстансе. Принципиально одно — доступ к этим данным идёт только через код самого сервиса, а не напрямую из чужого кода.

Реализация в 1С-Битрикс: модули и точки интеграции

Теперь конкретика — какими средствами самого Битрикса собрать связку «монолит + сервис». Хорошая новость: платформа даёт всё необходимое из коробки, экзотику писать не придётся.

  1. Исходящий вызов сервиса. Для синхронных обращений из Битрикса к сервису используйте HTTP-клиент ядра (Bitrix\Main\Web\HttpClient) с жёстким таймаутом и обработкой ошибок. Оборачивайте вызов так, чтобы падение сервиса не роняло страницу, а включало деградацию.
  2. Реакция на бизнес-события. Подпишитесь на события ядра (например, OnSaleOrderSaved, события каталога) через обработчики в init.php или своём модуле. В обработчике не делайте тяжёлую работу — только фиксируйте факт в outbox-таблице и отдавайте управление.
  3. Outbox на D7. Заведите свою ORM-сущность (highload-таблицу или обычную таблицу с классом-наследником Bitrix\Main\ORM\Data\DataManager) под журнал исходящих событий: ключ события, тип, полезная нагрузка, статус, число попыток.
  4. Отправитель. Публикацию событий из outbox в очередь вешайте на агент Битрикса или на отдельный cron-скрипт/демон. Агент проще, но для интенсивного потока лучше вынести отправку в постоянный процесс вне hit.
  5. Входящие вебхуки от сервиса. Для приёма результатов и внешних событий сделайте отдельный REST-эндпоинт (свой контроллер на D7 или входящий вебхук). Обязательно проверяйте подпись/токен запроса и обрабатывайте входящее идемпотентно.
  6. Хранение статусов. Результаты асинхронных операций складывайте в свойства заказа, свою таблицу или highload-блок, чтобы витрина могла их показать, когда пользователь вернётся или обновит страницу.

Так выглядит распределение ролей внутри Битрикса: событие ядра → обработчик → запись в outbox → агент-отправитель → очередь → сервис, и обратно: сервис → вебхук → контроллер → обновление статуса заказа. Никакой магии, всё на штатных механизмах: события, агенты, D7 ORM, HttpClient и REST.

Точки интеграции в ядре Битрикс Событие ядра OnSaleOrderSaved Обработчик init.php / модуль Outbox (D7) DataManager Агент → очередь публикация REST-контроллер вебхук от сервиса Статус заказа свойство / HL-блок
Схема: исходящий путь идёт от события ядра через обработчик и outbox к агенту-отправителю; входящий — от REST-контроллера к обновлению статуса заказа.

Наблюдаемость: логи, трейсинг и алерты

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

Минимальный набор, который стоит заложить сразу, а не «потом»:

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

Безопасность и разграничение доступа

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

Важно: «внутренняя сеть» — не гарантия безопасности. Стройте систему так, будто любой сетевой запрос может быть подделан: подпись, токен и проверка на каждом стыке. Особенно это касается эндпоинтов, меняющих деньги и статусы заказов.

Развёртывание и эксплуатация

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

АспектМонолит Битрикс+ Микросервис
ДеплойОдин процесс выкладкиОтдельный пайплайн на каждый сервис
МониторингОдин набор метрикМетрики и алерты по каждому сервису и очереди
База данныхОдна СУБДПлюс база сервиса и её резервные копии
ИнфраструктураВеб-сервер + СУБДПлюс брокер очередей, контейнеры, сеть
Отладка инцидентаОдин лог и стекСквозной трейсинг через процессы

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

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

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

Частые ошибки

Мини-FAQ. Обязательно ли брать «взрослый» брокер вроде Kafka? Нет. Для потока обычного магазина хватает более простого брокера (RabbitMQ, Redis Streams), а иногда — таблицы-очереди в базе с обработчиком по агенту. Начинайте с простого и усложняйте под реальную нагрузку, а не наоборот.

Чек-лист выноса сервиса

Сведём всё в практический список, по которому удобно принимать решение и проектировать вынос перед стартом работ:

  1. Боль названа. Есть конкретная метрика, инцидент или ограничение, которое монолит не тянет и которое снимет вынос.
  2. Граница проведена по бизнесу. Сервис отвечает за связную бизнес-возможность и владеет своими данными, а не режет систему по техническим слоям.
  3. Контракт узкий. Через границу проходит небольшой стабильный набор команд и событий, а не «дай мне строку из таблицы».
  4. Способ обмена выбран осознанно. Синхронный REST — где нужен мгновенный ответ; очередь — где операция долгая или должна пережить сбой.
  5. Надёжность заложена. Есть outbox, доставка «хотя бы один раз» и идемпотентная обработка по устойчивому ключу; предусмотрены dead letter queue и backoff.
  6. Данные изолированы. У сервиса своя база, доступ к ней — только через его код; чужие таблицы напрямую не читаются.
  7. Наблюдаемость готова. Структурированные логи, сквозной correlation id, метрики очереди и алерты настроены до запуска.
  8. Безопасность стыков. Аутентификация вызовов, проверка подписи вебхуков, закрытый сетевой периметр, минимум прав у токенов.
  9. Эксплуатация обеспечена. Есть отдельный деплой, резервное копирование базы сервиса и понимание, кто дежурит по инцидентам.

Вывод

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

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

Частые вопросы

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

Микросервис оправдан, когда конкретная задача не укладывается в модель и ритм жизни портала: тяжёлый расчёт, который блокирует hit пользователя, интеграция с внешней системой со своими лимитами и SLA, нагрузка, которую нельзя масштабировать вместе с монолитом, или технология, для которой PHP плохо подходит. Если же логика простая и живёт в том же цикле, что и остальной сайт, её дешевле держать внутри Битрикса. Не выносите в сервис то, что можно решить агентом, событием или модулем.

Чем обмениваться между Битрикс и микросервисом — REST или очередью?

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

Как не потерять и не задвоить сообщения при обмене через очередь?

Нужны три вещи: гарантированная запись события в исходящий журнал в той же транзакции, что и бизнес-изменение (outbox), доставка «хотя бы один раз» с повторами и идемпотентная обработка на стороне получателя по устойчивому ключу события. Тогда повтор доставки не создаст второй заказ, а временная недоступность сервиса не потеряет событие — оно доедет позже. Без идемпотентности любая ретрай-политика рано или поздно задвоит данные.

Где хранить данные — в базе Битрикса или в отдельной базе сервиса?

У микросервиса должна быть своя база данных, к которой не ходит напрямую ни Битрикс, ни другие сервисы. Общий доступ к таблицам ломает границы: любое изменение схемы становится рискованным, а сервисы перестают быть независимыми. Обмен идёт только через API и события, а не через общую СУБД. Исключение — осознанные интеграционные витрины только для чтения, но и их лучше строить как отдельный слой.

Не усложнят ли микросервисы поддержку небольшого магазина?

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

Поделиться:

Думаете, что часть логики пора вынести из Битрикса?

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

Услуга «Разработка»

Игорь Воскресенский

Основатель студии B2Bsite. С 2014 года команда разрабатывает и поддерживает интернет-магазины и корпоративные сайты на 1С-Битрикс, проектирует архитектуру, выносит тяжёлую логику в сервисы и настраивает надёжный обмен с внешними системами для среднего и крупного бизнеса.

← Все статьи блога