B2BPRO.KZ | Рекламное агентство в Алматы

Интеграция коробочного Битрикс24 с внешней базой данных

Разработчик за ноутбуком и два соединённых хранилища данных: интеграция коробочного Битрикс24 с внешней базой

Интеграция коробочного Битрикс24 с внешней базой данных строится двумя путями. Первый: обмен через REST API и вебхуки, когда порталу отдают готовые данные, а не доступ к таблицам. Второй: прямое подключение к сторонней СУБД, которое прописывается в секции connections файла /bitrix/.settings.php и вызывается из кода портала. Прямое подключение быстрее, но писать им в таблицы самого Битрикс24 нельзя.

Дальше картина, знакомая почти каждому владельцу коробки. Склад живёт в учётной системе, биллинг в собственной базе на PostgreSQL, отдел продаж сидит в Битрикс24, и менеджер держит в голове три окна сразу. Кто-то предлагает «просто подцепить базу напрямую», кто-то настаивает на обмене файлами по расписанию. Разницу между этими подходами считают в часах разработки, хотя важнее другое: сколько раз за год интеграция встанет после планового обновления портала.

Что такое внешняя база данных применительно к коробке

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

Сама коробка живёт на своей СУБД, и выбор здесь ограничен. В технических требованиях коробочного Битрикс24 указаны MySQL 8.x и PostgreSQL 11 и выше, причём PostgreSQL доступен только на лицензии «Энтерпрайз для Постгрес». Oracle и MSSQL не поддерживаются, PHP нужен версии 8.2 и выше. Это важно на старте: если внешняя система работает на MSSQL, речь пойдёт не о «подключим базу к порталу», а о промежуточном слое, который будет ходить в MSSQL своими средствами.

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

Когда прямое подключение оправдано, а когда хватит REST

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

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

На проектах B2BPRO.KZ мы чаще всего видим гибрид: справочники и тяжёлые выборки читаются напрямую из внешней базы, а всё, что меняет данные, идёт через API внешней системы. Такое разделение экономит и ресурсы сервера, и нервы при разборе инцидентов, потому что записи в чужую базу из портала просто не существует.

У каждого второго подрядчика при этом возникает соблазн писать напрямую в таблицы Битрикс24 в обход API. Так делать нельзя. Структуру таблиц никто не обещал сохранять, она меняется между обновлениями, а вокруг записи в CRM живут события, индексы поиска, счётчики и бизнес-процессы, которые прямой INSERT не запустит. Сделка появится в базе и не появится в воронке. Разбирать такое в поддержке дольше, чем написать интеграцию заново.

Как подключить вторую базу: секция connections в .settings.php

Дополнительное подключение описывается в файле /bitrix/.settings.php, в секции connections. Рядом с подключением default, через которое работает сам портал, добавляется ещё одно, со своим именем. В описании настроек ядра 1С-Битрикс перечислены ключи, которые задаются для каждого подключения:

  • className: класс, реализующий работу с конкретным типом СУБД, например \Bitrix\Main\DB\MysqliConnection;
  • host: адрес сервера базы, при необходимости с портом;
  • database: имя базы;
  • login и password: учётные данные;
  • options: флаги постоянного и отложенного соединения.

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

Получить такое соединение из кода можно методом Application::getConnection(). Документация по методу описывает его прямо: он возвращает соединение с базой данных указанного имени, а при пустом параметре отдаёт соединение по умолчанию. То есть Application::getConnection('billing') вернёт объект \Bitrix\Main\DB\Connection для базы биллинга, и дальше с ним работают обычными запросами.

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

Как заставить ORM работать с чужой базой

Прямые SQL-запросы к внешней базе работают, но у D7 есть вариант аккуратнее. Класс сущности наследуется от DataManager, и в нём переопределяется метод getConnectionName(). Официальное описание метода говорит, что он возвращает имя соединения для сущности, и в примере из документации метод отдаёт строку с именем соединения, прописанным в настройках.

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

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

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

Чем отличается чтение на лету от зеркала данных

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

Параметр Чтение на лету Зеркало (копия таблиц) Очередь событий
Актуальность данных Всегда текущая По расписанию обмена Близкая к текущей
Если внешняя база недоступна Раздел не открывается Портал работает на копии События копятся, обмен догоняет
Нагрузка на внешнюю систему Высокая, зависит от трафика Низкая, всплески по расписанию Средняя, равномерная
Сложность разработки Низкая Средняя Высокая
Типовая задача Справочники, остатки, история Аналитика, отчёты, поиск Заказы, статусы, платежи

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

Что ломается чаще всего

Чаще всего разбираться приходится с кодировками и типами данных. Внешняя база на cp1251, портал на utf8mb4, и казахские буквы в названиях контрагентов превращаются в вопросительные знаки. Лечится заданием кодировки соединения на этапе подключения, но обнаруживается обычно после того, как данные уже уехали в отчёт.

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

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

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

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

Сколько занимает такая интеграция

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

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

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

Безопасность и сеть: что закрыть до запуска

Внешняя база не должна быть доступна из интернета. Нормальная схема выглядит так: сервер СУБД слушает только внутренний интерфейс, портал ходит к нему по закрытому каналу внутри сети или через VPN, а список разрешённых адресов ограничен. Если база физически в другом дата-центре, канал шифруется.

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

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

Порядок работ: пошаговый план

  1. Описать, какие именно данные нужны порталу и в какую сторону они идут: список таблиц, полей и сценариев вместо формулировки «интеграция со складом».
  2. Проверить совместимость: тип и версия внешней СУБД, сетевая доступность, кодировка, часовой пояс.
  3. Выбрать схему обмена по таблице выше и зафиксировать её письменно вместе с владельцем внешней системы.
  4. Создать на стороне внешней базы отдельную учётную запись с минимальными правами и, при необходимости, представления для портала.
  5. Добавить соединение в секцию connections файла /bitrix/.settings.php и проверить его на тестовой копии портала, а не на боевом.
  6. Описать сущности через DataManager с переопределённым getConnectionName() и закрыть обращения к ним обработкой ошибок и ограничением по времени.
  7. Прогнать нагрузочный сценарий: не одна карточка, а список из полусотни записей и одновременная работа нескольких пользователей.
  8. Поставить на мониторинг доступность соединения и время ответа, завести оповещение на ответственного.
  9. Записать всё в документацию проекта: имя соединения, учётную запись, список таблиц, порядок действий при смене пароля.

Что учесть при обновлении коробки

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

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

Проверочный список после каждого обновления короткий: соединение поднимается, тестовая выборка возвращает данные, даты и кодировка на месте, время ответа не выросло. На это уходит пять минут, а без такой проверки инцидент обычно всплывает через неделю и разбирается целый день. Если поддерживать это некому, рутину проще передать партнёру вместе с остальным сопровождением портала: мы в B2BPRO.KZ ведём такие проверки регламентом, а не по факту жалоб.

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

Можно ли подключить внешнюю базу к облачному Битрикс24?

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

Сколько внешних баз можно подключить к одному порталу?

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

Можно ли писать данные напрямую в таблицы Битрикс24?

Делать этого нельзя. Структура таблиц портала меняется между обновлениями, а вокруг создания сделки или контакта работают события, индексы поиска и бизнес-процессы, которые прямой запрос в базу не запускает. Запись в портал выполняется только через API: REST для внешних систем и методы D7 для кода на сервере. Читать из базы напрямую для отчётов допустимо, писать нет.

Что делать, если внешняя система работает на MSSQL?

Коробочный Битрикс24 не поддерживает MSSQL и Oracle как свою СУБД, но это не значит, что интеграция невозможна. Обычно ставится промежуточный слой: небольшой сервис, который читает MSSQL своими средствами и отдаёт порталу данные по HTTP, либо регулярно выгружает нужные таблицы в базу, к которой портал уже умеет подключаться. Схему выбирают по объёму данных и требуемой свежести.

Как понять, что интеграция тормозит именно из-за внешней базы?

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

Прокрутить вверх