В практике разработчика 1С иногда возникают ситуации, которые на первый взгляд кажутся мистическими: длительный процесс, запущенный пользователем вручную, внезапно прерывается и начинает выполняться заново без каких-либо сообщений об ошибках. Особенно часто это проявляется при обмене данными с внешними системами, например, с сайтами на базе BITRIX. Рассмотрим подробнее, почему это происходит, и разберем механизмы платформы 1С:Предприятие 8.3, которые приводят к такому поведению.
Представим ситуацию: в конфигурации «Зарплата и управление персоналом 3.1» (клиент-серверный вариант) инициируется обмен данными. Процесс запускается нажатием кнопки на форме внешней обработки. Код отрабатывает корректно, данные уходят на сторону сайта, и 1С переходит в режим ожидания ответа. Однако спустя примерно 2 часа (или другой фиксированный интервал) процесс прерывается и управление магическим образом снова оказывается в начале серверной процедуры обмена.
Проанализируем стек вызовов в момент такого «повторного» старта. При обычном нажатии кнопки стек начинается с клиентской процедуры модуля формы. При самопроизвольном перезапуске клиентская часть в стеке отсутствует — выполнение начинается сразу с серверного метода. Это ключевой маркер, указывающий на то, что инициатором повтора выступает сама платформа 1С, а не пользователь или алгоритм на встроенном языке.
Одной из самых распространенных причин является настройка кластера 1С «Интервал перезапуска рабочих процессов». По умолчанию в консоли администрирования кластера часто установлено значение 7200 секунд, что в точности соответствует 2 часам.
Разберем, что происходит на уровне системы:
rphost.exe, в котором выполняется ваш серверный вызов, достигает лимита времени жизни.rphost завершает работу, связь обрывается.Именно поэтому мы видим «старт с сервера»: клиент просто дублирует последний отправленный запрос, на который не получил ответа. Для исправления этой ситуации на время длительных тестов попробуем установить значение интервала перезапуска в 0 (отключено) в консоли сервера 1С.
Длительные обмены часто сопровождаются обработкой больших массивов данных или формированием объемных XML-файлов. Если в настройках кластера задан параметр «Допустимый объем памяти», рабочий процесс может быть принудительно завершен при достижении этого порога.
Выясним причину через мониторинг ресурсов: если в момент перезапуска процесса в журнале событий Windows фиксируются ошибки завершения rphost.exe, значит, система аварийно завершает процесс, а механизм отказоустойчивости платформы инициирует повторный вызов процедуры со стороны клиента.
Основная архитектурная ошибка, приводящая к подобной «мистике» — выполнение длительных операций непосредственно в контексте серверного вызова из формы. Рассмотрим правильный подход с использованием механизма фоновых заданий. Это позволит сделать операцию независимой от стабильности сеанса и настроек перезапуска процессов.
Вместо прямого вызова серверной процедуры, перепишем алгоритм запуска обмена:
&НаКлиенте
Процедура ВыполнитьОбмен(Команда)
ПараметрыЗадания = Новый Структура;
ПараметрыЗадания.Вставить("УзелОбмена", Объект.УзелОбмена);
// Запускаем фоновое задание, которое не зависит от RPC-таймаутов клиента
Результат = ЗапуститьОбменНаСервере(ПараметрыЗадания);
Если Результат Тогда
ПодключитьОбработчикОжидания("ПроверитьСтатусОбмена", 5);
КонецЕсли;
КонецПроцедуры
На стороне сервера мы используем объект ФоновыеЗадания. Это гарантирует, что даже если рабочий процесс перезапустится, фоновое задание (если оно настроено с соответствующими параметрами) либо завершится с ошибкой, либо будет управляться менеджером заданий осознанно, а не «невидимым» повтором клиентского запроса.
&НаСервереБезКонтекста
Функция ЗапуститьОбменНаСервере(ПараметрыЗадания)
НаименованиеЗадания = "Ручной обмен с Битрикс";
// Проверяем, не запущено ли уже такое задание, чтобы избежать дублей
Отбор = Новый Структура("Наименование", НаименованиеЗадания);
Задания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Отбор);
Для Каждого Задание Из Задания Цикл
Если Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
ФоновыеЗадания.Выполнить("МодульОбмена.ВыполнитьПроцедуруОбмена", ПараметрыЗадания, , НаименованиеЗадания);
Возврат Истина;
КонецФункции
Проанализируем ситуацию, если 1С выступает в роли HTTP-клиента. При обмене с Битриксом часто используются HTTP-запросы. Если Битрикс долго обрабатывает данные (например, те же 2 часа), соединение может быть разорвано промежуточным звеном (Nginx, Apache) по таймауту. В некоторых версиях платформы (особенно в ветке 8.3.14) некорректная обработка разрыва соединения внутри кода обмена может приводить к повторному входу в цикл отправки.
Важные рекомендации по настройке кластера 1С:
8.3.14.1565, рассмотрите возможность обновления на более стабильные релизы (например, ветку 8.3.18 или выше), так как в старых релизах наблюдались специфические ошибки работы менеджера кластера с сеансами.Таким образом, «мистический» перезапуск кода — это штатная попытка платформы 1С спасти выполнение операции при падении или плановом перезапуске рабочего процесса. Лучший способ борьбы с этим — уход от длительных вызовов НаСервере в сторону асинхронного выполнения через фоновые задания.