Часто разработчики сталкиваются с ситуацией, когда созданное ими регламентное задание отлично отрабатывает при ручном запуске с клиента, но полностью отказывается работать по расписанию в фоновом режиме. В журнале регистрации пусто, ошибок нет, и кажется, что задание просто не запускается. Эта проблема особенно характерна для задач, требующих доступа к внешним ресурсам, например, к файловой системе или интернету.
Проанализируем классический случай: регламентное задание по загрузке курсов валют с сайта центрального банка. При запуске через консоль заданий в режиме «Выполнить на клиенте» все работает, а в режиме «Выполнить в фоновом задании» — нет. Разберем по шагам, почему так происходит и как это исправить.
Главная причина такого поведения кроется в том, что клиентский сеанс и фоновое задание выполняются в совершенно разных окружениях.
Когда вы запускаете код на клиенте:
Когда задание выполняется в фоновом режиме на сервере:
rphost.exe).USR1CV8.Именно эта разница в правах и настройках является корнем большинства проблем с фоновыми заданиями.
Чтобы найти точную причину, почему задание не работает, необходимо провести последовательную диагностику. Рассмотрим основные шаги.
Первое, что нужно сделать, — это проверить Журнал регистрации. Даже если задание «молча» не выполняется, там может быть запись об ошибке компиляции модуля или ошибке доступа. Если журнал пуст, это часто означает, что задание либо не стартует, либо падает на самом раннем этапе. В этом случае переходим к следующему шагу.
Самый надежный способ понять, на каком этапе «зависает» фоновое задание — это добавить в код запись отладочных сообщений в Журнал регистрации. Это позволит увидеть, до какой строчки кода доходит выполнение.
Важно: критические участки кода, особенно связанные с внешними ресурсами (файлы, интернет), необходимо оборачивать в блок Попытка...Исключение. В блоке Исключение нужно обязательно логировать текст ошибки.
Посмотрим на пример кода загрузки курсов валют и как его улучшить для отладки.
Исходный код автора:
Процедура jcpc_ЗагрузкаКурсовВалютФон() Экспорт
// ...
ЗаписьЖурналаРегистрации("Этап 1а");
// ...
Если ЗапроситьФайлыССервераВМодуле(...) <> Истина Тогда
Возврат;
КонецЕсли;
ЗаписьЖурналаРегистрации("Этап 1г");
// ...
КонецПроцедуры
Проблема этого кода в том, что если функция ЗапроситьФайлыССервераВМодуле вызовет исключение, выполнение просто прервется, и мы не увидим ни записи "Этап 1г", ни самой ошибки. Правильнее будет сделать так:
Процедура ЗагрузкаКурсовВалют() Экспорт
ЗаписьЖурналаРегистрации("ЗагрузкаКурсовВалют.Старт", УровеньЖурналаРегистрации.Информация,,,
"Начало выполнения регламентного задания.");
Попытка
СерверИсточник = "www.nationalbank.kz";
АдресРесурса = "/rss/get_rates.cfm?fdate=" + Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");
ИмяВходящегоФайла = ПолучитьИмяВременногоФайла("xml");
// Создаем HTTP-соединение
Соединение = Новый HTTPСоединение(СерверИсточник);
ЗаписьЖурналаРегистрации("ЗагрузкаКурсовВалют.Соединение", УровеньЖурналаРегистрации.Информация,,,
"Попытка получить данные с сервера " + СерверИсточник);
// Выполняем GET-запрос
Соединение.Получить(АдресРесурса, ИмяВходящегоФайла);
ЗаписьЖурналаРегистрации("ЗагрузкаКурсовВалют.Успех", УровеньЖурналаРегистрации.Информация,,,
"Файл успешно получен и сохранен в " + ИмяВходящегоФайла);
// ... дальнейшая обработка файла ...
Исключение
// Если произошла ошибка, мы ее поймаем и запишем в журнал
ТекстОшибки = "Ошибка при загрузке курсов валют: " + ОписаниеОшибки();
ЗаписьЖурналаРегистрации("ЗагрузкаКурсовВалют.Ошибка", УровеньЖурналаРегистрации.Ошибка,,, ТекстОшибки);
КонецПопытки;
ЗаписьЖурналаРегистрации("ЗагрузкаКурсовВалют.Финиш", УровеньЖурналаРегистрации.Информация,,,
"Завершение выполнения регламентного задания.");
КонецПроцедуры
С таким кодом в Журнале регистрации появится точное описание ошибки. В рассматриваемом случае автор в итоге получил ошибку: «Ошибка работы с Интернет: Не могу установить соединение». Это сразу указывает на проблему с сетью.
После получения информации из логов можно анализировать конкретные причины:
rphost.exe.Предупреждение(), Сообщить(), открытие форм), вызовет ошибку компиляции на сервере, и задание не запустится. Убедитесь, что ваш код является чисто серверным или используйте директивы компиляции (&НаСервере, &НаКлиенте).
USR1CV8 есть права на соответствующий каталог (например, на папку временных файлов, указанную в КаталогВременныхФайлов()).
Если диагностика показала, что проблема в доступе к интернету из-за прокси-сервера, есть несколько способов ее решить.
Это самый надежный и правильный способ, так как он не зависит от системных настроек сервера. Параметры прокси передаются напрямую при создании объекта HTTPСоединение.
// Создаем объект для настроек прокси-сервера
Прокси = Новый ИнтернетПрокси;
// Указываем параметры: протокол, адрес, порт, и если нужна авторизация - логин и пароль
Прокси.Установить("http", "proxy.my-company.ru", 8080, "proxy_user", "proxy_password");
// При создании HTTPСоединения передаем ему настроенный объект прокси
// Пятый параметр конструктора - это прокси
// Для сайтов с HTTPS (SSL) нужно также передать объект ЗащищенноеСоединениеOpenSSL
СерверИсточник = "www.nationalbank.kz";
Соединение = Новый HTTPСоединение(СерверИсточник, 443, , , Прокси, 20, Новый ЗащищенноеСоединениеOpenSSL());
// Дальнейшая работа с соединением
Попытка
Соединение.Получить(...);
Исключение
// ...
КонецПопытки;
Такой код будет работать независимо от того, под какой учетной записью запущена служба сервера 1С.
Можно изменить учетную запись, от имени которой запускается служба сервера 1С. Вместо стандартной USR1CV8 можно указать доменного пользователя, у которого есть настроенный доступ в интернет. Этот способ не рекомендуется с точки зрения безопасности, так как он предоставляет рабочему процессу 1С избыточные права, но может использоваться для быстрой диагностики или в небольших сетях с невысокими требованиями к безопасности.
Таким образом, «магия», из-за которой код работает на клиенте и не работает в фоне, сводится к разнице в окружении и правах. Правильная диагностика с помощью Журнала регистрации и отладочных сообщений, а также понимание серверной специфики позволяют быстро найти и устранить подобные проблемы.