Для чего нужно
Данная доработка призвана решить следующие проблемы стандартной конвертации данных:
1. Выгрузка данных (и загрузка соответственно) пакетом из неопределенного числа объектов. Т.е. всего что зарегистрировано в планах обмена. Это, в свою очередь, порождает неприятности в виде долгих блокировок.
Пробовали бороться:
- Ставить расписание обменов более часто не помогает. Возникают ситуации, когда надо обменять большую кучу объектов (поправили правила обмена например). Или много объектов возникает при массовых правках. В результате либо обмен падает (слишком большой файл например) либо работа пользователей встает из-за блокировок... Еще хуже получается, если выгрузка при этом проходит, но загрузка идет больше времени, чем интервал выгрузки. И получается, что новая выгрузка выгружает все объекты повторно. Получается замкнутый круг.
- Управлять размером пакета выгружаемых данных не получается, т.к. если задать размер пакета например 50, то не факт, то в эти 50 попадут нужные объекты и в базе приемнике не возникнут <Объект не найден>, т.е. некондиционные записи.
- Работать с обменом через СОМ-соединение тоже не всегда выходит - остаются проблемы блокировок в базе источнике, да и с доступами к COM на стороне сервера часто возникают проблемы (например у меня они вообще запрещены).
2. Ошибки обменов. Ошибка обмена часто не дает завершить обмен. И отправляющая база об этой ошибке не знает. И вновь возникает замкнутый круг - один выгружает одно и тоже, другой грузит все повторно, до повторения ошибки.
Долгим путем проб и ошибок был найден путь:
1. Выгружать надо не весь пакет, а только один объект. Т.к. данный обмен не распределенный, то движения документа не переносятся (их делает проведение документа в базе-приемнике) и риска возникновения движений без документа тут нет. Риск возникновения некондиции в виде <Объект не найден> тоже минимален - если правила обмена настроены правильно, то в базу приемник полетит 2 передачи - ссылка и связанная с этой ссылкой запись.
2. Использовать надо Конвертацию данных 2. Спецов по ней довольно много и править правила обмена довольно легко.
3. В качестве транспорта надо использовать RabbitMQ. Меньше головной боли от передачи файлов. Можно жить и на файлах. Но с кроликом просто проще - нет проблем с доступами и легче администрировать.
Как это работает
- Настраивается обмен данными через Конвертацию данных 2 с использованием плана обмена (желательно своего). Транспорт лучше использовать файловый. Проверяется его работоспособность.
- Загружается расширение. Оно приносит с собой:
- Несколько регистров сведений (далее РС) для хранения нужной информации.
- Несколько констант для хранения настроек сервера RabbitMQ.
- Регламентное задание, которое занимается выгрузкой и загрузкой данных через RabbitMQ.
- Регламентное задание, которое следит за состоянием обменов и генерирует отчеты об ошибках.
- Доработанную часть обработки конвертации данных. В ней доработана выгрузка. Вместо выгрузки всех зарегистрированных объектов в плане обмена, будет выгружаться только один. Но т.к. выгрузкой занимается рег.задание то выгрузка будет происходить столько раз, сколько зарегистрировано объектов.
- Настраивается соединение и расписания рег.заданий.
- Запускаются рег. задания
- Рег. задание выгрузки / загрузки надо настроить на запуск один раз в 60(шестьдесят) секунд. Длительность его работы регулируется в настройках циклов.
- Рег. задание генерирования отчета по ошибкам - раз в полчаса.
Расширение долно подойти к базам, построенным с использованием БСП.
Каждому узлу обмена в базах соответствует какая-то база отправитель+получатель. Например в базе "ЕРП" в плане обмена Обмен_ЕРП_ЗУП31 заведен узел "ЗУП31". Легко понять, что этому узлу соответствует база ЗУП31. В базе ЗУП31 также есть план обмена Обмен_ЕРП_ЗУП31. И в нем заведен узел "ЕРП". Местоположение баз для задачи не важно. Важно, что сервера ЕРП и ЗУП31 могут обратится к серверу RabbitMQ.
У каждого узла в RabbitMQ есть очереди:
1. Очередь, в которую текущая база выкладывает сообщения с выгруженными объектами.
2. Очередь, в которую другая база выкладывает квитанции с ответами на прием сообщений из первой очереди. Это отчеты о том, прочитан ли выгруженный объект или нет.
3. Очередь, в которую другая база выкладывает свои сообщения с выгруженными объектами.
4. Очередь, в которую текущая база выкладывает квитанции с ответами на прием сообщений из 3-ей очереди.
Т.е. для другой базы 3 и 4 очередь является 1 и 2, а 1 и 2 являются 3 и 4!
Настройки очередей хранятся в РС.чсНастройкиОчередейRabbitMQ. Пример записи в регистре настроек:

Список очередей на сервере RabbitMQ

Все очереди настроены однотипно. По сути вводилось название очереди и нажималось "Add queue".

Регламентное задание обмена каждого узла запускает 3 фоновых задания (ФЗ).
1. ФЗ, которое контролирует регистрации изменений в узле, и делает отправку объекта в очередь 1.
2. ФЗ, которое читает обратные квитанции о приеме объектов в очередь 2.
3. ФЗ, которое принимает выгруженные для нее объекты и формирует обратные квитанции. Т.е. работает с очередями 3 и 4
ФЗ выгрузки объектов.
- При старте инициализирует обработку Конвертация данных. Т.к. правила обмена данными между большими базами (например ЕРП - ЕРП) могут грузиться в обработку примерно минуту, имеет смысл делать это один раз.
- Запускается основной цикл работы ФЗ
- Для каждой регистрации изменения в плане обмена:
- Читает регистрацию изменения из плана обмена. Получается Объект.
- Делает выгрузку каждого объекта отдельно, используя обработку Конвертация данных
- Если формирование выгрузки неудачно, то делается запись в РС.чсОшибкиОбменаRabbitMQ
- Если формирование выгрузки удачно, то делается запись в РС.чсОтправленныеСообщенияRabbitMQ
- Удаляет изменение из плана обмена.
- Помещает квитанцию в очередь 1.
- Если поместить не удалось, то делается запись в РС.чсОшибкиОбменаRabbitMQ и удаляется запись из РС.чсОтправленныеСообщенияRabbitMQ
- Если нет новых регистраций, то делается ожидание (сколько секунд - указывается в настройках).
-
Блин, когда 1С сделает нормальную процедуру ожидания? Всего-то 30 лет прошу... Тут реализовано через вызов системной Pause. но этот подход не работает в файловом клиенте. Только на клиент-сервере...
-
- Сам цикл работает не более числа секунд, указанных в настройках
- Для каждой регистрации изменения в плане обмена:
Т.е. после того, как объект попал в регистрацию изменений плана обмена, он почти сразу:
- Отправляется получателю в очередь (если все успешно).
- Попадает в РС.чсОтправленныеСообщенияRabbitMQ (если все успешно).
- Попадает в РС.чсОшибкиОбменаRabbitMQ (если что-то пошло не так во время выгрузки. Чаще всего это ошибки настройки правил обмена).
- Удаляется из регистрации изменений.
ФЗ чтения обратных сообщений
- Читает обратную квитанцию из очереди 2 (через РС.чсПринятыеСообщенияRabbitMQ, которое чистится в конце цикла чтения).
- Из РС.чсОтправленныеСообщенияRabbitMQ удалаяется соответствующая запись.
- Проверяется так же РС.чсОшибкиОбменаRabbitMQ, т.к. если очередь 1 большая, то сообщение может быть уже там
- Если база-получатель рапортует об неудаче приема, то делается запись в РС.чсОшибкиОбменаRabbitMQ.
- Если очередь 2 пустая, то читает в РС.чсОтправленныеСообщенияRabbitMQ сообщения, которым более 15 минут (время настраивается в настройках). Если такие есть, то помещает запись в РС.чсОшибкиОбменаRabbitMQ и удаляет из РС.чсОтправленныеСообщенияRabbitMQ.
Т.е. если база-получатель рапортует об успехе приема, то объект исчезает из РС.чсОтправленныеСообщенияRabbitMQ (или РС.чсОшибкиОбменаRabbitMQ). И обмен объекта можно считать оконченным.
Если база рапортует об ошибках приема, то объект остается в РС.чсОшибкиОбменаRabbitMQ на дальнейший разбор причин неудачи специально обученными сотрудниками. Информацию о том, что что-то не сработало, им отправляет рег.задание генерации отчетов об ошибках.
ФЗ приема выгруженных объектов
- При старте инициализирует обработку Конвертация данных. Опять же что бы сэкономить время на загрузке правил.
- Запускается основной цикл работы ФЗ
- Читает объект из очереди 3 (через РС.чсПринятыеСообщенияRabbitMQ, которое чистится в конце цикла чтения).
- Делает загрузку объекта через обработку Конвертация данных (включая проведение документов).
- Если чтение неудачно, то формируется обратная квитанция с рапортом об ошибке.
- Если чтение удачно, то формируется обратная квитанция с рапортом об удаче.
- Обратная квитанция помещается в очередь 4.
- Если поместить не удалось, то делается запись в ЖР (это если сервер RabbitMQ внезапно исчез).
Работа с сервером RabbitMQ
Вся работа с сервером выполняется через Web-интерфейс сервера RabbitMQ.
Тут есть тонкость - прочитав сообщение с сервера RabbitMQ есть вероятность его потери (например при внезапной ошибке на сервере 1С). Поэтому сообщение сначала ложится в РС.чсПринятыеСообщенияRabbitMQ и только потом обрабатывается. После его обработки оно удаляется из этого регистра. Если в процессе обработки происходит фатальная ошибка (т.е. сеанс прервался или возникло необработанное исключение), то сообщение остается в РС.чсПринятыеСообщенияRabbitMQ. И при следующем запуске, в качестве прочитанного сообщения из очереди, будет предоставлено именно оно.
Проверено на следующих конфигурациях и релизах:
- 1С:Управление холдингом 3.2 (русский и английский интерфейсы), релизы 3.2.7.4
Вступайте в нашу телеграмм-группу Инфостарт