Приветствуем вас! Сегодня мы разберем одну очень интересную и распространенную проблему, с которой сталкиваются разработчики и системные администраторы при переходе на современный стек работы с файловыми базами через автономный сервер 1С (ibsrv).
Представьте ситуацию: у вас настроена связка из двух регламентных заданий. Первое задание (РЗ-1) работает по жесткому расписанию (например, каждые 5 минут), мониторит внешние события и при их наличии динамически меняет расписание второго регламентного задания (РЗ-2) на однократный запуск в определенное время. Раньше, когда база запускалась в обычном файловом режиме через специальный "технический сеанс", все работало отлично. Но после перехода на автономный сервер ibsrv второе регламентное задание просто перестает запускаться в назначенное время. При этом, если параллельно подключиться к базе обычным клиентом, планировщик "просыпается" и задание мгновенно отрабатывает.
Давайте подробно разберем, почему возникает это поведение, проанализируем внутренние механизмы платформы 1С и рассмотрим несколько надежных архитектурных решений этой проблемы.
---
Для того чтобы понять суть проблемы, нам нужно заглянуть во внутреннюю архитектуру автономного сервера 1С. Когда вы используете файловую базу данных через ibsrv, этот процесс берет на себя роль полноценного сервера приложений. Он сам управляет сессиями, блокировками и, что самое главное, планировщиком регламентных заданий.
Когда первое регламентное задание (РЗ-1) выполняется внутри фонового процесса, оно успешно перезаписывает расписание для РЗ-2. Эти данные физически сохраняются в системных таблицах базы данных 1Cv8.1CD. Однако планировщик самого автономного сервера работает по принципу кэширования сетки расписаний.
В отличие от полноценного клиент-серверного варианта под управлением кластера (где за синхронизацию отвечает менеджер кластера rmngr), автономный сервер в файловом режиме не всегда динамически отслеживает изменения системных таблиц, сделанные «изнутри» изолированной сессии фонового задания. Процесс планировщика продолжает ориентироваться на тот пул задач и расписаний, который был сформирован при его старте или при инициализации сессий веб-сервера. Измененное «на лету» расписание для него просто не существует до тех пор, пока не произойдет принудительный сброс кэша или инициализация нового планировщика.
---
Почему же РЗ-2 запускается, если зайти в базу напрямую через Тонкий или Толстый клиент по файловому пути?
Когда вы подключаетесь к файловой базе напрямую, минуя автономный сервер, ваша клиентская сессия запускает собственный фоновый поток планировщика. Этот «клиентский» планировщик считывает актуальные данные из таблиц базы данных напрямую с диска, видит измененное и актуальное расписание РЗ-2 и тут же берет его на исполнение.
Важное предупреждение: Одновременная работа с файловой базой напрямую (через локальную сеть или общий диск) и через запущенный автономный сервер ibsrv категорически не рекомендуется фирмой 1С! Это прямой путь к конфликтам блокировок, рассинхронизации кэшей планировщика и, в худшем случае, к повреждению структуры базы данных. Все подключения, включая служебные и технические, должны осуществляться строго через адрес автономного сервера (по протоколам HTTP/TCP).
---
Поскольку динамическое изменение расписаний регламентных заданий «на лету» является классическим архитектурным «антипаттерном» в экосистеме 1С (который часто сбоит даже на крупных клиент-серверных кластерах), мы рекомендуем отказаться от этой схемы в пользу более стабильных вариантов.
Этот подход полностью исключает необходимость перезаписи метаданных расписания в процессе работы системы. Вместо изменения расписания РЗ-2 мы будем использовать вспомогательный регистр сведений в качестве очереди задач.
Рассмотрим реализацию этого паттерна по шагам:
ОчередьЗадач со следующей структурой:
ИдентификаторЗадачи (Тип: УникальныйИдентификатор или Строка).ДатаЗапуска (Тип: Дата), ПараметрыЗапуска (Тип: ХранилищеЗначения).
// Выполняется в первом регламентном задании при наступлении события
Процедура ЗарегистрироватьЗадачуВОчереди(ПараметрыДействия, ВремяЗапуска) Экспорт
МенеджерЗаписи = РегистрыСведений.ОчередьЗадач.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИдентификаторЗадачи = Новый УникальныйИдентификатор();
МенеджерЗаписи.ДатаЗапуска = ВремяЗапуска;
МенеджерЗаписи.ПараметрыЗапуска = Новый ХранилищеЗначения(ПараметрыДействия);
Попытка
МенеджерЗаписи.Записать(Истина);
Исключение
ЗаписьЖурналаРегистрации("ОчередьЗадач", УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
// Основной обработчик РЗ-2, который запускается часто по фиксированному расписанию
Процедура ВыполнитьЗадачиИзОчереди() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОчередьЗадач.ИдентификаторЗадачи КАК ИдентификаторЗадачи,
| ОчередьЗадач.ПараметрыЗапуска КАК ПараметрыЗапуска
|ИЗ
| РегистрСведений.ОчередьЗадач КАК ОчередьЗадач
|ГДЕ
| ОчередьЗадач.ДатаЗапуска <= &ТекущееВремя";
Запрос.УстановитьПараметр("ТекущееВремя", ТекущаяДата());
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Извлекаем параметры задачи
ПараметрыЗадачи = Выборка.ПараметрыЗапуска.Получить();
// Выполняем полезную работу
Попытка
ВыполнитьПолезноеДействие(ПараметрыЗадачи);
// После успешного выполнения удаляем задачу из очереди
МенеджерЗаписи = РегистрыСведений.ОчередьЗадач.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИдентификаторЗадачи = Выборка.ИдентификаторЗадачи;
МенеджерЗаписи.Удалить();
Исключение
ЗаписьЖурналаРегистрации("ОчередьЗадач", УровеньЖурналаРегистрации.Предупреждение,,,
"Ошибка выполнения задачи: " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Этот подход гарантирует 100% стабильность работы на любом типе сервера (включая автономный файловый сервер ibsrv), так как база данных работает со стандартными транзакционными таблицами регистра сведений, а не с метаданными планировщика.
---
Если специфика вашей бизнес-логики требует, чтобы второе действие выполнялось не строго в фиксированное время на календаре, а просто асинхронно и сразу после завершения логики первого задания, то использовать второе регламентное задание вообще не нужно.
Вместо этого мы можем запустить фоновое задание напрямую из кода первого регламентного задания с помощью программных средств платформы. Проанализируем пример кода:
// Код выполняется в конце работы Первого регламентного задания
Процедура ПослеВыполненияМониторинга(ПараметрыСобытия)
// Подготавливаем параметры для передачи в фоновое задание
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(ПараметрыСобытия);
// Запускаем фоновое задание напрямую на автономном сервере
ФоновыеЗадания.Выполнить(
"МойОбщийМодуль.ВыполнитьВтороеДействиеАсинхронно",
МассивПараметров,
"УникальныйКлючВторогоЗадания",
"Асинхронная обработка события"
);
ЗаписьЖурналаРегистрации("ЗапускЗадачи", УровеньЖурналаРегистрации.Информация,,,
"Фоновое задание успешно запущено напрямую.");
КонецПроцедуры
При использовании метода ФоновыеЗадания.Выполнить() автономный сервер создает новый изолированный поток и выполняет логику мгновенно, полностью обходя планировщик регламентных заданий и его кэши.
---
Если вам требуется жестко регламентированный запуск задачи в определенные часы, а внутренний планировщик файлового автономного сервера в силу специфики релиза платформы работает нестабильно, можно переложить задачу управления расписанием на операционную систему.
Для этого мы можем использовать Планировщик задач Windows (Task Scheduler) или cron в Linux. Алгоритм настройки выглядит следующим образом:
.epf), которая выполняет логику второго задания при открытии, либо пропишите вызов метода в модуле управляемого приложения при параметре запуска.run_job.bat):
:: Запуск сеанса 1С под техническим пользователем для выполнения обработки
"C:\Program Files\1cv8\8.3.XX.XXXX\bin\1cv8c.exe" ENTERPRISE /S "localhost\MyBase" /N "Robot_Scheduler" /P "StrongPassword" /Execute "C:\1C_Scripts\ExecuteJob.epf" /C "ПараметрДействия"
---
Мы проанализировали особенности работы автономного сервера 1С с планировщиком задач в файловом режиме. Попытки динамически менять расписания регламентных заданий «на лету» часто приводят к зависанию задач из-за архитектурного кэширования процессов в ibsrv.
Использование проверенного паттерна «Очередь задач через Регистр сведений» (Вариант А) или прямого программного вызова фоновых заданий (Вариант Б) позволит вам навсегда забыть о проблемах с планировщиком и обеспечит стабильную и отказоустойчивую работу вашей информационной системы на автономном сервере.