Задание включено, расписание стоит, ошибок в журнале нет, а данные не приходят. Открываешь форму "Регламентные и фоновые операции", видишь зелёную галочку "Использование" и пустую колонку результата, и дальше непонятно, куда смотреть.
Короткий ответ: почти все причины такого молчания лежат в местах, которых форма списка не показывает. Флаг на кластере 1С, признак копии базы у БСП, пользователь в карточке задания, расписание, которое никогда не наступит. А самая неприятная из них, задание под пользователем, которого нет в базе, на платформе 8.3.27 не оставляет в журнале регистрации ни одной строки. Я проверил это на стенде: задание пыталось стартовать каждые несколько секунд, журнал за это время не записал о нём ничего.
Этот разбор вырос из прошлой статьи, Регламентное задание не запускалось шестнадцать месяцев: там причиной оказалась учётная запись из другой базы в поле "Имя пользователя". После неё мы собрали стенд на копии УТ 11.5 с живыми данными и прошли по очереди все места, где задание может застрять. Ниже восемь мест по порядку проверки, у каждого код и то, что показал стенд.
Почему форма списка тут не помогает
Форма из библиотеки стандартных подсистем (БСП) показывает, чем кончился последний запуск. Если запусков не было вовсе, в колонке результата пусто, и пустота выглядит как порядок: ошибок нет, красного нет. Это правда только наполовину. Ошибок нет, потому что коду задания негде было упасть: он не выполнялся.
Отсюда общий принцип всех восьми проверок. Статус здесь ничего не скажет, смотрим причины, по которым статуса может не быть, и историю: были ли запуски вообще и кто их делал, сервер или человек.
1. Флаг "Блокировка регламентных заданий" на кластере
Самая массовая по последствиям причина: не выполняется ни одно задание базы. Флаг стоит в свойствах информационной базы на кластере, его ставят на копиях, чтобы тест не начал слать обмены в боевые системы. Потом копию делают рабочей, а флаг забывают.
Изнутри базы его видно через сервер администрирования (RAS, служба рядом с агентом сервера 1С). Объект АдминистрированиеСервера я проверял на 8.3.27, код берёт первый кластер:
Админка = Новый АдминистрированиеСервера("localhost", 1545); Админка.ВыполнитьАутентификацию(); Кластер = Админка.ПолучитьКластеры()[0]; Кластер.ВыполнитьАутентификацию(ЛогинКластера, ПарольКластера); Для Каждого База Из Кластер.ПолучитьИнформационныеБазы() Цикл Если База.Имя = "ИмяБазы" Тогда База.ВыполнитьАутентификацию(ЛогинАдминистратораБазы, ПарольАдминистратораБазы); Сообщить("Блокировка: " + База.БлокировкаРегламентныхЗаданий + ", СУБД: " + База.СУБД); КонецЕсли; КонецЦикла;
Здесь два затыка, и оба я словил на стенде.
Первый: без аутентификации администратора самой базы кластер ошибку не выдаёт, он молча возвращает значение по умолчанию. На стенде с включённым флагом код без строки База.ВыполнитьАутентификацию напечатал "Блокировка: Нет", после неё "Да". Отличить честное "нет" от "мне не показали" можно по соседнему свойству: у клиент-серверной базы тип СУБД пустым не бывает, а без администратора он приходит пустой строкой.
Второй: неверный пароль администратора базы через RAS считается неудачной попыткой входа. Несколько таких подряд, и платформа блокирует вход этому пользователю, в том числе в саму базу. Длительность зависит от настроек базы, у нас это были пять минут, и HTTP-сервисы базы под этой учёткой всё это время отвечали отказом. Проверять пароли на боевом администраторе таким способом не стоит.
Тот же ответ из командной строки даёт rac infobase info --cluster=<кластер> --infobase=<база> --infobase-user=<администратор> --infobase-pwd=<пароль> localhost:1545, строка scheduled-jobs-deny: on значит блокировку. Только rac - клиент того же RAS, и без запущенной службы он тоже не ответит (а установка платформы RAS не запускает). Тогда остаётся консоль "Администрирование серверов 1С": флаг стоит в свойствах информационной базы.
Коварная деталь: при включённом флаге кнопка "Выполнить сейчас" в форме БСП работает. На стенде я трижды запустил задание вручную при включённой блокировке, все три раза оно отработало. Снаружи база выглядит живой, если кто-то довозит работу руками. Поэтому ручные запуски в истории - повод смотреть этот флаг первым.
2. БСП решила, что база стала копией
У БСП свой механизм защиты копий: если сменилась строка соединения, база считает себя перемещённой и блокирует работу с внешними ресурсами. При входе администратор видит окно с вопросом, а задания, которые работают с внешними ресурсами (обмены, загрузки с сайтов), при первом старте отменяются и выключаются самой БСП. Так же БСП выключает задания, которые обращаются к интернету, если в настройках программы запрещён доступ к интернет-сервисам.
В карточке задания потом стоит снятая галочка "Использование", и выглядит это так, будто кто-то выключил задание руками. Список выключенных таким способом БСП хранит сама:
Параметры = Константы.ПараметрыБлокировкиРаботыСВнешнимиРесурсами.Получить().Получить(); Если ТипЗнч(Параметры) = Тип("Структура") Тогда // пока БСП не завела параметры, там Неопределено Сообщить("Работа с внешними ресурсами заблокирована: " + Параметры.РаботаСВнешнимиРесурсамиЗаблокирована); Для Каждого ИмяСписка Из СтрРазделить("ОтключенныеЗадания,ОтключенныеЗаданияПриОтключенииДоступаКИнтернетСервисам", ",") Цикл Для Каждого Ид Из Параметры[ИмяСписка] Цикл Сообщить("Выключено БСП: " + РегламентныеЗадания.НайтиПоУникальномуИдентификатору(Ид)); КонецЦикла; КонецЦикла; КонецЕсли;
Значение Неопределено у флага означает "решение ещё не принято": окно при входе никто не закрыл, а блокировка уже действует. В причине блокировки БСП пишет, какая строка соединения была и какая стала.
Рядом живут ещё три проверки из того же места в коде БСП (ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания): конфигурация ждёт обновления версии, узел распределённой базы (РИБ) потерял связь с главным и не установлены региональные настройки. В каждом из этих случаев задание стартует, сразу отменяет само себя и пишет об этом в журнал. Касается это заданий, которые в начале вызывают ПриНачалеВыполненияРегламентногоЗадания: у типовых так, у самописных как повезёт. Такие хотя бы видно, если журнал открыть.
3. Поле "Имя пользователя": тот самый тихий случай
Задание выполняется от имени пользователя из своей карточки. Если там стоит учётная запись, которой в базе нет (перенесли обработку из другой базы или удалили уволенного), сеанс под задание не стартует.
На стенде я завёл задание с пользователем Сидоров_из_другой_базы и расписанием каждые 20 секунд, снял блокировку на кластере и смотрел две минуты. Что осталось после:
| Где смотрел | Что там |
|---|---|
| журнал регистрации | ни одной записи об этом задании: ни запуска, ни ошибки |
свойство ПоследнееЗадание |
Неопределено |
| список фоновых заданий сервера | попытки примерно каждые 10 секунд, чаще расписания, каждая "завершено с ошибками": "Неверно указан пользователь или пароль. Неправильное имя пользователя" |
Единственный след живёт в памяти сервера и пропадает при его перезапуске. Если сервер перезагружали после переноса, следов нет совсем. Поэтому история тут не поможет, проверять надо само поле (под администратором, иначе список пользователей не прочитать):
Для Каждого Задание Из РегламентныеЗадания.ПолучитьРегламентныеЗадания() Цикл Если НЕ ПустаяСтрока(Задание.ИмяПользователя) И ПользователиИнформационнойБазы.НайтиПоИмени(Задание.ИмяПользователя) = Неопределено Тогда Сообщить(Задание.Наименование + ": пользователя """ + Задание.ИмяПользователя + """ в базе нет"); КонецЕсли; КонецЦикла;
Пустое поле, наоборот, нормально: в типовой УТ оно пустое у всех предопределённых заданий, и на стенде задание без пользователя отработало без замечаний.
4. Роли и вход пользователя задания
Я ожидал, что пользователь без прав тоже не даст заданию стартовать. Стенд показал обратное.
Задание под пользователем без единой роли отработало за две минуты шесть раз, задание под пользователем, у которого выключены все виды входа (ни пароля, ни ОС), семь раз. Расписание у обоих каждые 20 секунд, разница в один запуск от того, в какую секунду окна каждое стартовало первым. Платформа не требует входа для регламентных, и БСП этим пользуется: её служебный пользователь для серверных оповещений заведён ровно так, без ролей и без входа, и его задание на стенде тоже выполнилось.
Опасность пользователя без ролей в другом: задание стартует, а его код упадёт на первом обращении к данным, если оно идёт не в привилегированном режиме. На стенде такого кода не попалось, типовое удаление временных файлов работает привилегированно. Поэтому этот пункт в моей проверке жёлтый: задание идёт, но за его код ручаться нельзя.
5. Задание выключено функциональной опцией
У БСП есть таблица зависимостей: какое задание нужно при какой функциональной опции. Если опция выключена, задание при первом старте отменяется и само себя выключает, так написано в ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания. Проверить заранее можно тем же методом, которым пользуется БСП:
Модуль = ОбщегоНазначения.ОбщийМодуль("РегламентныеЗаданияСлужебный"); Зависимости = Модуль.РегламентныеЗаданияЗависимыеОтФункциональныхОпций(); Доступно = Модуль.РегламентноеЗаданиеДоступноПоФункциональнымОпциям(Метаданные.РегламентныеЗадания.ИмяЗадания, Зависимости);
Практический смысл двоякий. Выключенное задание с выключенной опцией - это норма, так и задумано. А вот включённое задание при выключенной опции при первой же попытке отменится с текстом "недоступно по функциональным опциям" и выключится. На копии УТ такое нашлось у одного из типовых заданий: галочка стоит, а опция, от которой оно зависит, выключена.
6. Расписание, которое не наступит
Два частых случая. Первый: в расписании стоит дата окончания в прошлом, обычно после разового переноса или теста. Второй: условия противоречат друг другу, и окно не наступит никогда. Классика: 31-е число в месяце "февраль". Окно "с 20:00 по 8:00", кстати, не ошибка: оно переходит через полночь, так стоит типовая проверка ведения учёта, и ТребуетсяВыполнение честно отвечает "да" в 23:00 и в 03:00.
Проверять глазами тут бесполезно, у платформы есть функция, которая отвечает, нужен ли запуск в этот момент:
Расписание = Задание.Расписание; Если ЗначениеЗаполнено(Расписание.ДатаКонца) И Расписание.ДатаКонца < ТекущаяДата() Тогда Сообщить("Расписание кончилось " + Расписание.ДатаКонца); КонецЕсли; // дата последнего автозапуска берётся из журнала, как в пункте 7 Нужно = Расписание.ТребуетсяВыполнение(ТекущаяДата(), ДатаПоследнегоЗапуска);
У ТребуетсяВыполнение есть особенность, которую я узнал только прогоном: без даты последнего запуска функция проверяет лишь попадание в окно. На стенде расписание "раз в 7 дней с 1 сентября" без второго параметра ответило "да" на 2 сентября. Поэтому вопрос "должно ли было задание сработать с прошлого раза" задаётся только вместе с датой прошлого запуска, а вопрос "наступит ли расписание вообще" перебором дат на год вперёд.
7. История: сервер запускал или человек
В прошлой статье все 580 записей в журнале самого механизма оказались ручными прогонами. Как отличить такие запуски по журналу регистрации, показал стенд, и разница видна в одной колонке:
| Признак | Запуск по расписанию | "Выполнить сейчас" в форме БСП |
|---|---|---|
| событие | _$Job$_.Start |
_$Job$_.Start |
| колонка "Метаданные" | РегламентноеЗадание.ИмяЗадания |
пусто |
| колонка "Данные" | наименование задания | "Запуск вручную: наименование" |
| работает при флаге блокировки на кластере | нет | да |
Отбор = Новый Структура("ДатаНачала, ИмяПриложения, Событие", ТекущаяДата() - 30 * 86400, "BackgroundJob", "_$Job$_.Start"); Журнал = Новый ТаблицаЗначений; ВыгрузитьЖурналРегистрации(Журнал, Отбор, "Дата, Метаданные, Данные"); Для Каждого Запись Из Журнал Цикл ИмяМетаданных = Запись.Метаданные; Если ТипЗнч(ИмяМетаданных) = Тип("Массив") Тогда // у части событий метаданных несколько ИмяМетаданных = ?(ИмяМетаданных.Количество() > 0, ИмяМетаданных[0], ""); КонецЕсли; ВидЗапуска = ?(СтрНачинаетсяС(Строка(ИмяМетаданных), "РегламентноеЗадание."), "сервер", "вручную"); КонецЦикла;
Ошибка запуска пишется событием _$Job$_.Error уровня "Ошибка" с текстом в комментарии, успешный конец - _$Job$_.Finish. Если журнал настроен писать только ошибки, ничего этого в нём нет: запуски пишутся уровнем "Информация".
Одно предупреждение для старых платформ. По нашему прошлому замеру на 8.3.20.2290 отбор журнала стоил до 2,6 миллисекунды на каждую отобранную строку, и месяц истории частых заданий читается минутами. Читать лучше сутками от сегодняшнего дня назад, а дальние дни добирать отбором по метаданным только тех заданий, у которых запусков не нашлось.
8. Запускается, но работает вхолостую
Во второй истории прошлой статьи задание стартовало 288 раз в сутки, а работа появлялась только днём. Холостой запуск в журнале видно по сеансу. Берём номер сеанса из события _$Job$_.Start и смотрим, были ли в нём события изменения данных до _$Job$_.Finish:
События = Новый Массив; События.Добавить("_$Data$_.New"); События.Добавить("_$Data$_.Update"); События.Добавить("_$Data$_.Delete"); События.Добавить("_$Data$_.Post"); События.Добавить("_$Data$_.Unpost"); Изменения = Новый ТаблицаЗначений; // Запуск - пара событий Start и Finish одного сеанса из выгрузки пункта 7 ВыгрузитьЖурналРегистрации(Изменения, Новый Структура("ДатаНачала, ДатаОкончания, Сеанс, Событие", Запуск.Начало, Запуск.Конец, Запуск.Сеанс, События), "Метаданные"); Вхолостую = Изменения.Количество() = 0;
Транзакции для этого не годятся: у БСП каждый запуск пишет свою служебную отметку, поэтому _$Transaction$_.Commit есть и у совершенно пустого запуска. Критерий только _$Data$_. На стенде задание удаления временных файлов, которому нечего было удалять, дало ноль событий изменения за 24 запуска, а задание заполнения параметров расширений за один запуск дало 30 событий изменения регистра.
Холостой запуск не всегда поломка. Задание, которое только отправляет данные наружу, может честно ничего не менять в базе. Но для задания, которое должно загружать или пересчитывать, серия пустых запусков - это вопрос, откуда оно берёт работу.
Что показал стенд целиком
Управление торговлей 11.5.22.67, БСП 3.1.11.189, платформа 8.3.27.1606, MS SQL. Флаг блокировки на кластере включён (так и должно быть у копии), БСП считает базу копией. Автозапуски набраны за две минуты, пока флаг был снят, потом я его вернул. Заданий стенда десять, каждое под свой случай:
| Задание стенда | Что обработка сказала |
|---|---|
| пользователь из другой базы | не выполняется: пользователя нет, в журнале пусто, в памяти сервера попытки с ошибкой входа |
| только ручные запуски (тоже чужой пользователь) | то же, плюс "все записи в истории - ручные запуски" |
| расписание с датой окончания в прошлом | не выполняется: расписание кончилось |
| 31 февраля | не выполняется: расписание не наступит ни разу за год |
| пользователь без ролей | внимание: стартует, но код без прав |
| вход запрещён, удаление временных файлов | вхолостую: запускается, данные не меняет |
| пользователь не указан, то же удаление | вхолостую |
| под администратором, то же удаление | вхолостую |
| заполнение параметров расширений | норма: запускается и пишет данные |
| выключено | выключено |
Когда в проверку добавлен администратор базы и флаг кластера прочитан, красными становятся все включённые задания, а главной строкой встаёт "на кластере включена блокировка регламентных заданий". Это честный итог для копии: сервер не запустит ни одно задание, какая бы ещё причина ни сидела в карточке. У заданий с чужим пользователем и с расписанием, которое кончилось или не наступит, своя причина при этом остаётся первой: снимут флаг, а они всё равно не пойдут.
Счётчики обработки я сверил с журналом, прочитанным без неё: автозапуски четырёх заданий стенда и три ручных запуска совпали до единицы, флаг совпал с ответом rac.
Всё это в одной кнопке
Проходить восемь пунктов руками по каждому заданию долго, поэтому я собрал их во внешнюю обработку "Регламентное задание не выполняется: почему". Кнопка "Проверить все" даёт по каждому заданию цветной вердикт и одну строку причины, "Подробно" раскрывает все восемь проверок с тем, что сделать. Флаг кластера она читает, если указать администратора базы, без него честно пишет "нет данных". Результат выгружается в Markdown, чтобы отдать нейросети или приложить к заявке. Задания и настройки обработка не меняет, только читает.
Где это не проверено
Стенд один: УТ 11.5.22.67 на платформе 8.3.27.1606 и MS SQL. Поведение задания под несуществующим пользователем на других версиях я не проверял. В прошлой статье платформа молчала так же, но версию того сервера я не знаю.
Файловую базу стенд не покрывает. Там кластера нет, а задания выполняет один из открытых сеансов 1С, так что при закрытых сеансах они не запускаются вовсе.
Критерий "вхолостую" видит только то, что попадает в журнал как изменение данных. Если у вас журнал настроен писать только ошибки, пункты 7 и 8 проверить нечем.
Частые вопросы
Задание включено, ошибок нет. С чего начать? С истории: были ли за последний месяц запуски по расписанию, а не ручные. Если ни одного, причина в пунктах 1-6, и первым смотреть флаг на кластере.
Почему в журнале регистрации нет ни одной ошибки по заданию? Потому что код задания не выполнялся. Флаг на кластере, выключенное задание, кончившееся расписание и пользователь, которого нет, до кода не доходят, а значит и ошибке негде возникнуть.
Можно ли узнать флаг блокировки, не заходя в консоль кластера? Да, через АдминистрированиеСервера из самой базы, но только под администратором этой базы: без него кластер отдаёт "выключена" по умолчанию. Нужен запущенный RAS; без него флаг видно только в консоли "Администрирование серверов 1С".
Пользователь задания заблокирован или без прав. Задание встанет? По стенду на 8.3.27 нет: задания под пользователем без ролей и под пользователем без единого вида входа запускались. Встаёт задание, у которого пользователь из карточки в базе отсутствует.
Как отличить ручной запуск от запуска по расписанию? По журналу: у запуска планировщиком в событии _$Job$_.Start заполнены метаданные задания, у "Выполнить сейчас" из формы БСП они пустые, а в данных стоит "Запуск вручную".
Задание выключилось само. Кто его выключил? Чаще всего сама БСП: при смене строки соединения (база решила, что она копия) или при выключенной функциональной опции. Первый список лежит в константе ПараметрыБлокировкиРаботыСВнешнимиРесурсами, в поле ОтключенныеЗадания.
Задание отрабатывает каждые пять минут, а данных нет. Это поломка? Не обязательно. Посмотрите, есть ли в сеансах его запусков события изменения данных. Если нет ни одного, задание берёт работу из пустой очереди или не с того узла. Для задания, которое только отправляет данные наружу, это нормально.
Другие наши инструменты диагностики 1С:
- Чек-ап сервера 1С: настройки кластера и рабочих процессов - все свойства баз на кластере с вердиктом, включая блокировку регламентных и начала сеансов.
- Журнал регистрации, свёрнутый для нейросети - когда задание запускается и падает, ошибки из журнала удобнее разбирать сводкой.
- Анализ нагрузки кластера 1С - если задание стартует, но не успевает, смотреть надо, кто в это время держал базу.
- Чек-ап СУБД под 1С - регламентные операции самой СУБД, которые часто путают с заданиями 1С.
Вопрос к тем, у кого много баз: как вы узнаёте, что регламентное задание перестало работать, раньше, чем об этом скажут пользователи? Смотрите дату последнего изменения данных или ждёте звонка?
Вступайте в нашу телеграмм-группу Инфостарт