Как выбрать технологию для обмена данными между двумя базами 1С в разных городах?

Программист 1С v8.3 (Управляемые формы)
← На главную

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

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

Общие принципы и факторы выбора технологии обмена

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

  1. Объем и частота передаваемых данных: Отправляем ли мы небольшие справочники несколько раз в день или огромные массивы документов раз в неделю? Это определяет, насколько важна пропускная способность и задержки.
  2. Срочность доставки: Нужен ли обмен в режиме реального времени или допустима задержка в несколько часов?
  3. Идентичность или различия конфигураций: Если конфигурации сильно различаются, нам потребуются более гибкие механизмы трансформации данных.
  4. Необходимость модификации метаданных: Можем ли мы свободно изменять конфигурации обеих баз или одна из них находится на полной поддержке и ее изменения крайне нежелательны?
  5. Безопасность: Насколько критичны передаваемые данные? Какие требования к их защите от перехвата и подмены?
  6. Сложность реализации и поддержки: Насколько мы готовы вкладываться в настройку дополнительного ПО и разработку сложного кода?
  7. Гарантии доставки и порядок сообщений: Важно ли нам быть уверенными, что каждое сообщение будет доставлено, и в каком порядке?

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

Варианты технологий обмена данными

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

1. XML через FTP

Этот метод является одним из самых простых и понятных. Он основан на передаче файлов, содержащих данные, сериализованные в формат XML, через протокол FTP.

Как это работает?

В одной базе 1С мы выгружаем необходимые данные (например, элементы справочников или документы) в XML-файл. Затем этот файл передается на FTP-сервер. Другая база 1С в другом городе подключается к тому же FTP-серверу, скачивает файл и загружает данные из XML в свою информационную базу.

Преимущества:

Недостатки:

Пример кода (псевдокод) для XML через FTP:

База-источник:


// Создаем объект XMLЗапись
ЗаписьXML = Новый XMLЗапись();
ЗаписьXML.УстановитьИмяФайла("C:\Temp\ДанныеДляОбмена.xml"); // Локальный путь
ЗаписьXML.ЗаписатьОбъявлениеXML();

// Записываем данные в XML (например, элементы справочника)
ЗаписьXML.ЗаписатьНачалоЭлемента("Данные");
Выборка = Справочники.Контрагенты.Выбрать();
Пока Выборка.Следующий() Цикл
    ЗаписьXML.ЗаписатьНачалоЭлемента("Контрагент");
    ЗаписьXML.ЗаписатьАтрибут("Код", Выборка.Код);
    ЗаписьXML.ЗаписатьАтрибут("Наименование", Выборка.Наименование);
    ЗаписьXML.ЗаписатьКонецЭлемента(); // Контрагент
КонецЦикла;
ЗаписьXML.ЗаписатьКонецЭлемента(); // Данные
ЗаписьXML.Закрыть();

// Передача файла на FTP-сервер
FTPСоединение = Новый FTPСоединение("ftp.example.com", , "user", "password");
FTPСоединение.УстановитьТекущийКаталог("/uploads");
FTPСоединение.Загрузить("C:\Temp\ДанныеДляОбмена.xml", "ДанныеДляОбмена.xml");

База-приемник:


// Скачивание файла с FTP-сервера
FTPСоединение = Новый FTPСоединение("ftp.example.com", , "user", "password");
FTPСоединение.УстановитьТекущийКаталог("/uploads");
FTPСоединение.Загрузить("ДанныеДляОбмена.xml", "C:\Temp\ДанныеДляОбмена.xml"); // Локальный путь

// Чтение XML-файла
ЧтениеXML = Новый XMLЧтение();
ЧтениеXML.УстановитьИмяФайла("C:\Temp\ДанныеДляОбмена.xml");

Пока ЧтениеXML.Прочитать() Ци
    Если ЧтениеXML.Имя = "Контрагент" И ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
        Код = ЧтениеXML.ПолучитьАтрибут("Код");
        Наименование = ЧтениеXML.ПолучитьАтрибут("Наименование");
        
        // Поиск или создание контрагента в базе-приемнике
        КонтрагентОбъект = Справочники.Контрагенты.НайтиПоКоду(Код);
        Если КонтрагентОбъект = Неопределено Тогда
            КонтрагентОбъект = Справочники.Контрагенты.СоздатьЭлемент();
            КонтрагентОбъект.Код = Код;
        Иначе
            КонтрагентОбъект = КонтрагентОбъект.ПолучитьОбъект();
        КонецЕсли;
        КонтрагентОбъект.Наименование = Наименование;
        КонтрагентОбъект.Записать();
    КонецЕсли;
КонецЦикла;
ЧтениеXML.Закрыть();

2. Web-сервисы

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

Как это работает?

В 1С Web-сервисы реализуются на основе механизма XDTO (XML Data Transfer Objects). XDTO позволяет нам описывать структуру XML-файлов для входящих и исходящих данных, оперируя прикладными понятиями 1С. Для работы Web-сервисов требуется публикация информационной базы на веб-сервере (например, Apache или IIS).

Преимущества:

Недостатки:

Пример кода (псевдокод) для Web-сервисов:

Определение Web-сервиса в конфигураторе:

  1. В дереве конфигурации находим ветку Web-сервисы.
  2. Создаем новый Web-сервис.
  3. Определяем операции, которые он будет предоставлять (например, ПолучитьСписокКонтрагентов, СоздатьЗаявку).
  4. Для каждой операции указываем параметры и возвращаемые значения, используя XDTO-пакеты, которые мы предварительно создаем в конфигурации (ветка XDTO-пакеты).
  5. Публикуем информационную базу на веб-сервере через меню "Администрирование -> Публикация на веб-сервере...".

Пример вызова Web-сервиса из 1С:


// URL к WSDL-описанию Web-сервиса
// Например: http://<адрес_сервера>/<имя_публикации>/ws/<имя_сервиса>.1cws?wsdl
АдресWSDL = "http://api.example.com/MyService.1cws?wsdl";

// Создаем объект WSОпределения
Попытка
    Определение = Новый WSОпределения(АдресWSDL);
Исключение
    Сообщить("Ошибка при получении WSDL: " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

// Создаем прокси Web-сервиса
// ПространствоИменСервиса, ИмяСервиса, ИмяПорта - можно найти в WSDL
ИмяПространстваИмен = "http://www.example.com/MyService"; 
ИмяСервиса = "MyService";
ИмяПорта = "MyServiceSoap"; 

Прокси = Новый WSПрокси(Определение, ИмяПространстваИмен, ИмяСервиса, ИмяПорта);

// Вызываем операцию Web-сервиса
// Предположим, у нас есть операция "ПолучитьДанныеКонтрагента" с параметром "Код"
ПараметрКод = "000000001";
Попытка
    Результат = Прокси.ПолучитьДанныеКонтрагента(ПараметрКод);
    Сообщить("Получены данные: " + Результат.Наименование);
Исключение
    Сообщить("Ошибка вызова Web-сервиса: " + ОписаниеОшибки());
КонецПопытки;

3. HTTP-сервисы

HTTP-сервисы являются более современным и гибким подходом по сравнению с Web-сервисами, особенно в контексте REST-архитектуры. Они основаны на "голом" HTTP и позволяют использовать различные форматы передачи данных, включая JSON, XML и простой текст.

Как это работает?

В 1С мы создаем HTTP-сервис, определяем его базовый URL и шаблоны URL для различных методов (GET, POST, PUT, DELETE). Для каждого шаблона мы пишем обработчик HTTP-метода на встроенном языке 1С. Эти сервисы также требуют публикации информационной базы на веб-сервере (Apache или IIS).

Преимущества:

Недостатки:

Пример кода (псевдокод) для HTTP-сервисов:

Определение HTTP-сервиса в конфигураторе:

  1. В дереве конфигурации находим ветку HTTP-сервисы.
  2. Создаем новый HTTP-сервис, указываем базовый URL (например, /api/v1).
  3. Добавляем шаблоны URL, например, /documents/orders для работы с заявками.
  4. Для каждого шаблона определяем методы (GET, POST, PUT, DELETE) и связываем их с серверными процедурами общего модуля или модуля HTTP-сервиса.

Пример обработчика POST-запроса в 1С:


// В модуле HTTP-сервиса или в общем модуле, который связан с HTTP-сервисом
&НаСервере
Процедура ПринятьЗаявку(Запрос, Ответ)
    // Запрос - это объект HTTPСервисЗапрос
    // Ответ - это объект HTTPСервисОтвет

    Попытка
        // Получаем тело запроса как строку
        ТекстЗапроса = Запрос.ПолучитьТелоКакСтроку();

        // Создаем объект для чтения JSON
        ЧтениеJSON = Новый ЧтениеJSON();
        ЧтениеJSON.УстановитьСтроку(ТекстЗапроса);

        // Читаем данные из JSON
        ДанныеЗаявки = ПрочитатьJSON(ЧтениеJSON);
        ЧтениеJSON.Закрыть();

        // Пример: ДанныеЗаявки могут быть структурой или соответствием
        // Например, { "Номер": "З001", "Дата": "2023-10-27", "Контрагент": "Покупатель1" }
        Сообщить("Получена заявка: Номер " + ДанныеЗаявки.Номер + ", Дата " + ДанныеЗаявки.Дата);

        // Создаем новую заявку в базе-приемнике
        НоваяЗаявка = Документы.Заявка.СоздатьДокумент();
        НоваяЗаявка.Номер = ДанныеЗаявки.Номер;
        НоваяЗаявка.Дата = ДанныеЗаявки.Дата;
        // ... заполняем другие реквизиты ...
        НоваяЗаявка.Записать();

        // Формируем ответ об успешном приеме
        РезультатОтвета = Новый Структура("Статус, Сообщение", "OK", "Заявка успешно принята");
        ЗаписьJSON = Новый ЗаписьJSON();
        ЗаписьJSON.УстановитьСтроку();
        ЗаписатьJSON(ЗаписьJSON, РезультатОтвета);
        
        Ответ.КодСостояния = 200; // OK
        Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть(), КодировкаТекста.UTF8, "application/json");

    Исключение
        // В случае ошибки формируем ответ с кодом ошибки
        РезультатОтвета = Новый Структура("Статус, Сообщение", "ERROR", ОписаниеОшибки());
        ЗаписьJSON = Новый ЗаписьJSON();
        ЗаписьJSON.УстановитьСтроку();
        ЗаписатьJSON(ЗаписьJSON, РезультатОтвета);

        Ответ.КодСостояния = 500; // Внутренняя ошибка сервера
        Ответ.УстановитьТелоИзСтроки(ЗаписьJSON.Закрыть(), КодировкаТекста.UTF8, "application/json");
    КонецПопытки;
КонецПроцедуры

4. OData (Open Data Protocol)

OData — это открытый веб-протокол для запроса и обновления данных, который позволяет выполнять операции с ресурсами (такими как элементы справочников или документы) с помощью стандартных HTTP-команд (GET, POST, PUT, DELETE) и получать ответы в форматах XML или JSON.

Как это работает?

Платформа 1С, начиная с версии 8.3.5, предоставляет встроенную поддержку доступа к данным через OData. После публикации информационной базы на веб-сервере и активации поддержки OData для необходимых объектов метаданных, 1С автоматически создает REST-интерфейс. Это позволяет нам получать структуру метаданных и сами объекты с установленными фильтрами.

Преимущества:

Недостатки:

Пример кода (псевдокод) для OData:

Включение поддержки OData для объекта метаданных в конфигураторе:

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


// В модуле менеджера справочника "Контрагенты"
Процедура УстановитьСоставСтандартногоИнтерфейсаOData() Экспорт
    СтандартныеИнтерфейсыOData.УстановитьСоставСтандартногоИнтерфейсаOData(Истина, Метаданные.Справочники.Контрагенты);
КонецПроцедуры

После публикации базы на веб-сервере, мы сможем обращаться к данным контрагентов по URL:


// Пример URL для получения списка контрагентов в JSON-формате
// http://<адрес_сервера>/<имя_публикации>/odata/standard.odata/Catalog_Контрагенты?$format=json

// Пример URL для получения конкретного контрагента по ID
// http://<адрес_сервера>/<имя_публикации>/odata/standard.odata/Catalog_Контрагенты(guid'...')?$format=json

// Пример URL для фильтрации контрагентов по наименованию
// http://<адрес_сервера>/<имя_публикации>/odata/standard.odata/Catalog_Контрагенты?$filter=Description eq 'МойКонтрагент'&$format=json

5. RabbitMQ

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

Как это работает?

RabbitMQ действует как "транспортная компания" для наших сообщений. Мы отправляем "посылку" (сообщение) в RabbitMQ, который гарантирует ее доставку "другу" (другой базе 1С). Сообщения помещаются в очереди, из которых их могут забирать потребители. RabbitMQ обеспечивает асинхронное взаимодействие, гарантированную доставку и сохранение порядка сообщений.

Преимущества:

Недостатки:

Пример кода (псевдокод) для RabbitMQ:

База-источник (отправка сообщения):


// Предполагаем, что внешняя компонента PinkRabbitMQ уже подключена
// Например: ПодключитьВнешнююКомпоненту("PinkRabbitMQ");

Попытка
    // Создаем клиент RabbitMQ и подключаемся к серверу
    Клиент = Новый PinkRabbitMQ.Клиент();
    Клиент.Подключиться("amqp://guest:guest@localhost:5672/"); // Укажите актуальные параметры

    // Подготавливаем данные для отправки (например, структура заявки)
    ДанныеЗаявки = Новый Структура("Номер, Дата, Сумма", "З001", ТекущаяДата(), 1500.00);
    // Сериализуем данные в JSON-строку для передачи
    ЗаписьJSON = Новый ЗаписьJSON();
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, ДанныеЗаявки);
    СтрокаСообщения = ЗаписьJSON.Закрыть();

    // Отправляем сообщение в точку обмена с определенным ключом маршрутизации
    Клиент.ОтправитьСообщение("ExchangeЗаявки", "RoutingKeyЗаявки", СтрокаСообщения);
    Сообщить("Сообщение с заявкой отправлено в RabbitMQ.");

    Клиент.Отключиться();
Исключение
    Сообщить("Ошибка при отправке сообщения в RabbitMQ: " + ОписаниеОшибки());
КонецПопытки;

База-приемник (получение сообщения):


// Предполагаем, что внешняя компонента PinkRabbitMQ уже подключена

Попытка
    // Создаем клиент RabbitMQ и подключаемся к серверу
    Клиент = Новый PinkRabbitMQ.Клиент();
    Клиент.Подключиться("amqp://guest:guest@localhost:5672/"); // Укажите актуальные параметры

    // Получаем сообщение из очереди
    // ИмяОчереди должно быть настроено в RabbitMQ и связано с ExchangeЗаявки
    Сообщение = Клиент.ПолучитьСообщение("QueueЗаявки");

    Если Сообщение.ЕстьСообщения Тогда
        // Десериализуем данные из JSON-строки
        ЧтениеJSON = Новый ЧтениеJSON();
        ЧтениеJSON.УстановитьСтроку(Сообщение.ТелоСообщения);
        ДанныеЗаявки = ПрочитатьJSON(ЧтениеJSON);
        ЧтениеJSON.Закрыть();

        Сообщить("Получено сообщение с заявкой: Номер " + ДанныеЗаявки.Номер + ", Сумма " + ДанныеЗаявки.Сумма);
        
        // Здесь мы обрабатываем полученные данные, например, создаем документ "Заявка"
        НоваяЗаявка = Документы.Заявка.СоздатьДокумент();
        НоваяЗаявка.Номер = ДанныеЗаявки.Номер;
        НоваяЗаявка.Дата = ДанныеЗаявки.Дата;
        НоваяЗаявка.Сумма = ДанныеЗаявки.Сумма;
        // ... другие поля ...
        НоваяЗаявка.Записать();
        Сообщить("Документ Заявка создан.");

        // Подтверждаем RabbitMQ, что сообщение успешно обработано и может быть удалено из очереди
        Клиент.ПодтвердитьСообщение(Сообщение.DeliveryTag);
    Иначе
        Сообщить("В очереди QueueЗаявки нет новых сообщений.");
    КонецЕсли;

    Клиент.Отключиться();
Исключение
    Сообщить("Ошибка при получении или обработке сообщения из RabbitMQ: " + ОписаниеОшибки());
КонецПопытки;

Рекомендации по выбору технологии обмена с учетом наших условий

Исходя из нашей задачи — обмениваться парой справочников и заявок, пару раз в день, и все это мы будем программировать сами — давайте подведем итоги:

  1. HTTP-сервисы выглядят наиболее привлекательным вариантом. Они предлагают хороший баланс простоты и функциональности. Код для них писать несложно, они эффективно работают через интернет, поддерживают удобный формат JSON и позволяют организовать двухсторонний обмен с подтверждением. Это отличный вариант для синхронизации небольших объемов данных (справочников, документов) в достаточно оперативном режиме.
  2. XML через FTP также является рабочим и простым вариантом, особенно если у нас есть возможность обеспечить безопасность FTP (например, через VPN) или передаваемые данные не являются критически важными. Для обмена небольшим количеством файлов пару раз в день это вполне допустимо, но требует собственной реализации контроля доставки.
  3. Web-сервисы — тоже хороший вариант, особенно если в одной из баз уже есть существующая инфраструктура, использующая SOAP. Однако HTTP-сервисы часто считаются более современными и гибкими для большинства задач.
  4. RabbitMQ — это мощный инструмент для случаев, когда критически важна гарантированная асинхронная доставка, сохранение порядка сообщений и высокая масштабируемость. Однако для нашего сценария с "парой справочников и заявок" его использование может быть избыточным, поскольку потребует установки и настройки дополнительного сервера, что увеличивает сложность системы.
  5. OData — отличный выбор для предоставления стандартизированного доступа к данным 1С внешним системам (например, для чтения данных на сайте или в мобильном приложении). Для полноценного двухстороннего обмена данными между двумя базами 1С он менее гибок, чем HTTP-сервисы.

Важные аспекты безопасности при обмене данными через интернет

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

  1. HTTPS вместо HTTP: Всегда используйте протокол HTTPS для публикации веб-сервисов и HTTP-сервисов. Это обеспечивает шифрование трафика и защиту от перехвата данных. Не забывайте о проверке подлинности сертификата сервера для исключения атак типа "человек посередине" (MitM).
  2. Не "палите базу": Мы никогда не должны предоставлять прямой и неограниченный доступ к нашей базе данных из интернета. Публикация сервисов должна быть строго контролируемой.
  3. Фильтрация и проверка данных: Все данные, поступающие от клиента, должны быть тщательно проверены, экранированы и очищены, чтобы минимизировать риски SQL-инъекций и XSS-атак.
  4. Разграничение прав доступа: Ограничивайте административные права, используйте строгие роли и разграничивайте доступ к базам СУБД. Предоставляйте сервисам только минимально необходимые права.
  5. Защита хранилища токенов: Если используются токены аутентификации (например, JWT, Cookie), обеспечьте их безопасность с помощью флагов HttpOnly, Secure, SameSite и других механизмов.
  6. Шифрование данных и резервные копии: Рассмотрите возможность шифрования баз данных и обязательно устанавливайте пароли на резервные копии.

Заключение

Для нашей задачи с обменом "пары справочников и заявок пару раз в день" при самостоятельном программировании, HTTP-сервисы представляют собой наиболее оптимальный и современный выбор. Они обеспечивают достаточную гибкость, производительность и удобство разработки при адекватном уровне контроля над безопасностью. При этом, если требуется максимально простая реализация и есть возможность обеспечить безопасность канала, то XML через FTP также может быть рассмотрен. Каждый из методов имеет свои сценарии использования, и наш выбор должен быть обусловлен тщательным анализом всех требований и возможностей.

← На главную