gifts2017

Лекарство от зависших регламентных заданий

Опубликовал Александр Лукин (i_lo) в раздел Администрирование - Системное

Методика автоматического лечения зависших регламентных заданий

В одной внедряемой информационной системе значение регламентных заданий (РЗ) оказалось очень велико. С помощью них осуществляется автоматизированная проверка и загрузка исходных данных в систему. И надо же было такому случиться, РЗ стали иногда подвисать. Несколько раз в месяц, после перезапуска сервера 1С Предприятия, все РЗ переставали выполняться. Выяснилось, что ситуация легко локально лечится перезаписью каждого РЗ. После чего они начинают нормально работать.

Поиск в Инете показал, что мы не одиноки. Подобная проблема встречается давно, но есть нюансы. Один из хорошо известных случаев, когда сервер sql и сервер 1С стоят на одной машине. После физического перезапуска сервера сервис 1С Предприятия стартует раньше сервиса sql, и модуль обработки регламентных заданий не может ещё прочитать их из базы. И считает, что их нет. Есть даже рекомендация Микрософт для данной ситуации, которая предусматривает настройку зависимости сервиса 1С Предприятия от сервиса sql. То есть он всегда буде стартовать после. Решение! Но это был не наш случай, так как физического перезапуска сервера у нас не было. Только остановка и старт сервиса. Были проанализированы и другие аспекты. Сервер sql работает непрерывно. Базы в кластер если и добавляются, то порядком реже, чем сбоят РЗ. Разделителей нет. После перезапуска сервера 1С Предприятия РЗ стартуют независимо.

Попытка обсуждения на партнерском форуме 1С ни к чему не привела - https://partners.v8.1c.ru/forum/t/1171054/m/1171054. Не смотря на проявленное внимание со стороны сотрудников 1С, рекомендаций по решению не было.

В голове бродили идеи внешнего контроля над работой РЗ. Можно было бы использовать ЦКК, но он только информирует и не исправляет ошибки. Можно было бы запускать 1С с параметром с помощью системного планировщика раз в день, проверять и перезаписывать зависшие РЗ. Но тут на партнерском форуме попалось похожее решение от Евграфова Андрея - https://partners.v8.1c.ru/forum/t/916015/m/1103984. Суть его решения похожа на описанное выше, но метод, на мой взгляд, интереснее. Планировщик запускает vbs, а он в свою очередь запускает через COM 1С и вызывает модуль для контроля РЗ.
Модуль vbs передльно прост:

Dim v82, base
Set v82 = CreateObject("V82.ComConnector")
ConnString = "Srvr=имя_сервера;Ref=имя_базы"
Set base = v82.Connect(ConnString)
base.CheckScheduledTasks

В зависимости от настроек, в строку соединения возможно придется добавить пользователя и пароль: "usr=пользователь;pwd=пароль".

В конфигурацию я добавил процедуру в Модуль внешнего соединения, которая вызывает процедуру из Общего модуля:

Процедура CheckScheduledTasks() Экспорт
   
РегламентныеЗадания.ПроверитьПерезаписатьРегламентныеЗадания();
КонецПроцедуры

// Процедура проверяет выполнение и перезаписывает все включенные регламентные задания
Процедура ПроверитьПерезаписатьРегламентныеЗадания() Экспорт
   
мРЗ = РегламентныеЗадания.ПолучитьРегламентныеЗадания(Новый Структура("Использование", Истина));

    Если
мРЗ.Количество() = 0 тогда
       
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Информация,,,"Отсутствуют Регламентные задания с признаком Использование");
    КонецЕсли;

   
стрТекущееВремя = "00010101"+Формат(Час(ТекущаяДата()),"ЧЦ=2; ЧН=00; ЧВН=")+Формат(Минута(ТекущаяДата()),"ЧЦ=2; ЧН=00; ЧВН=")+
       
Формат(Секунда(ТекущаяДата()),"ЧЦ=2; ЧН=00; ЧВН=");
   
ТекущееВремя = Дата(стрТекущееВремя);

   
мПозже = Новый Массив;
   
фПерезаписываем = Ложь;

    Для каждого
РЗ из мРЗ цикл
        Если
РЗ.Расписание.ВремяНачала > ТекущееВремя тогда
           
мПозже.Добавить(РЗ);
        ИначеЕсли
РЗ.ПоследнееЗадание = Неопределено тогда
           
РЗ.Записать();
           
фПерезаписываем = Истина;
           
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Предупреждение,РЗ.Метаданные,РЗ,"Перезаписано - "+РЗ.Метаданные.Имя);
        Иначе
           
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Информация,РЗ.Метаданные,РЗ,"Нормально выполняется - "+РЗ.Метаданные.Имя);
        КонецЕсли;
    КонецЦикла;

    Если
фПерезаписываем тогда
        Для каждого
РЗ из мПозже цикл
           
РЗ.Записать();
           
ЗаписьЖурналаРегистрации("Регламентные задания",УровеньЖурналаРегистрации.Предупреждение,РЗ.Метаданные,РЗ,"Перезаписано - "+РЗ.Метаданные.Имя
);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

Последний модуль был доработан. Обрабатываются все используемые РЗ. Если РЗ должно было начать выполняться до момента проверки, но не выполнялось, то перезаписываем его. Если были обновления, то перезаписываем и более поздние РЗ.

Получилась заглушка, но, как показала практика, весьма эффективная!

Благодарность - Андрею Евграфову!!!

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Никита Коротаев (bforce) 24.11.13 21:43
У нас тоже такое было. Но, кажется, на 17-й платформе. Потом это как-то самой собой разрешилось... то ли перерегистрацией базы в кластере, то ли вместе с обновлением платформы. Сейчас такой проблемы нет.

Я спрошу у коллег, может кто-то помнит.
2. Александр Лукин (i_lo) 24.11.13 22:00
(1) bforce, коллеги боролись с этим ещё на 8.1, а у нас ситуация была на 8.2.18.82. Поэтому не стал писать версию платформы...
Вчера переехали на 8.2.19. Понаблюдаем. Будет продолжаться, попробую перерегистрацию в кластере. Спасибо!
3. Сергей Старых (tormozit) 24.11.13 23:39
У этого метода есть негативная сторона - при любой записи регламентного задания у него сбрасывается внутренний реквизит ДатаПоследнегоВыполнения и оно сразу запускается, если конечно остальные настройки расписания позволяют.
4. Александр Лукин (i_lo) 25.11.13 01:45
(3) tormozit, у РЗ есть реквизит ПоследнееЗадание, типа ФоновоеЗадание, которое в свою очередь имеет реквизит Конец, типа дата. В нашем случае прекращают формироваться фоновые задания и реквизит ПоследнееЗадание равен Неопределено! Именно на это и идет проверка. И после перезаписи РЗ начинают правильно выполняться в соответствии с настройками расписания. В чем же вы видите негативную сторону?
5. Юрий Осипов (yuraos) 27.11.13 09:09
Любопытно
....
Как раз сейчас по-крупному ковыряюсь с регламентными и фоновыми заданиями.
6. Юрий Осипов (yuraos) 27.11.13 09:16
(4) i_lo,
я думаю, что уважаемый (3) tormozit имеет ввиду,
что если перезаписать регламентное задание с установленным флагом использования,
то оно практически всегда стартует заново (с нюансами расписания я не экспериментировал),
что может быть не совсем к месту (например, если оно только-что выполнено).
7. Юрий Осипов (yuraos) 27.11.13 09:33
(3) tormozit,
можно вопрос на засыпку:
В документации сказано, что из списка фоновых заданий (всех регламентных и без расписания)
удаляются записи самых ранних неактивных (завершенных) заданий,
если общее число записей в списке превышает 1000.
---
может ли это обстоятельство "поломать" график выполнения заданий,
если расписание детально расписано по времени суток ???
...
ну например если другие фоновые задания запускаются в среднем раз 10 секунд ???
8. Никита Коротаев (bforce) 27.11.13 10:17
Мы с коллегами вспомнили еще один факт, который помогал избегать проблем с регламентными заданиями.

В расписании задания на закладке Дневное расписание мы обязательно добавляли хотя бы одну строку в тч Детальное расписание дня (она добавляется с тем же расписанием). Тогда нам это помогало. После перезапуска сервера задания, в которых эта строка была, стартовали без проблем. Другие - нет.

Сейчас, когда я проверяю наши задания, то вижу, что эта строка присутствует не везде, хотя проблем с заданиями нет.
9. Олег Филиппов (comol) 27.11.13 10:39
А ещё в эту функцию можно добавить получение списка регламентных заданий, чтение их расписания и запуска :). Самый верный способ :).
10. Сергей Старых (tormozit) 27.11.13 10:45
(3) История не используется при принятии решения о запуске. Я ж вроде объяснил, что используется внутренний реквизит регламентного задания ДатаПоследнегоВыполнения, который автоматически очищается при его записи.
11. VVV (V_V_V) 27.11.13 11:51
На одной нетленке регламентные задания висли по банальной причине - криво написанный код их выполнения. После выпрямления рук проблема ушла. Может стоит глянуть в эту сторону, а не костыли ставить?
И исторически сложилось, что никогда не разделяю сервера 1C и SQL (около десятка машин по всем филиалам). Ни разу не довелось столкнуться с проблемой позднего зажигания SQL...
12. Александр Лукин (i_lo) 27.11.13 11:59
(6) yuraos, наверное, я не очень хорошо прокомментировал код... Если РЗ выполнялось, то его реквизит ПоследнееЗадание будет иметь определенное значение. И перезаписи не произойдет. А если значение Неопределено, то как раз и нужно протолкнуть РЗ. Тогда оно перезаписывается и, если расписание позволяет, выполняется.
13. Александр Лукин (i_lo) 27.11.13 12:03
(7) yuraos, полагаю, что на выполнение это никак не повлияет. Это скорее, как очистка журнала. Где-то читал, что оперативная информация о выполненных фоновых заданиях хранится в памяти сервера. Например, если сервер 1С перезагрузить, то в консоли РЗ будут некие старые цифры...
14. Александр Лукин (i_lo) 27.11.13 12:08
(9) comol, я дико извиняюсь, но вот я получаю список используемых РЗ:

РегламентныеЗадания.ПолучитьРегламентныеЗадания(Новый Структура("Использование", Истина)),

потом анализирую время запуска:

Если РЗ.Расписание.ВремяНачала > ТекущееВремя тогда,

потом наличие последнего фонового задания:

ИначеЕсли РЗ.ПоследнееЗадание = Неопределено тогда

Только после этого перезаписываю...
15. Александр Лукин (i_lo) 27.11.13 12:14
(10) tormozit, хотелось бы уточнить. Кто принимает решение о запуске? Менеджер РЗ? Реквизит ДатаПоследнегоВыполнения является внутренним и недоступным из кода? В справке его нет. Чем плохо очищать этот реквизит, если РЗ и так стоит?
16. Александр Лукин (i_lo) 27.11.13 12:34
(11) V_V_V, занятно. В месяце 22 рабочих дня. 20 из низ 10 РЗ выполняются без проблем, а 2 дна все 10 подвисают, причем именно после перезапуска сервера 1С. И замечательно продолжают работать после перезаписи!!! Не верится ), но я посмотрю первое задание, которое выполняется после перезапуска сервера...
17. Олег Филиппов (comol) 27.11.13 14:46
(14) i_lo, так после этого можно и выполнить их уже :). Я к этому
18. Юрий Осипов (yuraos) 27.11.13 16:36
(14) i_lo,
не все так просто с расписаниями.
они достаточно хитро устроены.
Лучше использовать объект "РасписаниеРегламентногоЗадания".
у него есть специально предназначенный метод:

РасписаниеРегламентногоЗадания (JobSchedule)
ТребуетсяВыполнение (ExecutionRequired)
Синтаксис:

ТребуетсяВыполнение(<ДатаДляПроверки>, <ДатаНачалаПоследнегоЗапуска>, <ДатаЗавершенияПоследнегоЗапуска>)
Параметры:

<ДатаДляПроверки> (необязательный)

Тип: Дата.
Дата, для которой нужно проверить расписание. Если дата не задана, используется текущая дата.
<ДатаНачалаПоследнегоЗапуска> (необязательный)

Тип: Дата.
Дата начала последнего запуска регламентного задания. Если дата задана, то используется для проверки таких условий как ПериодПовтораДней, ПериодНедель, ПериодПовтораВТечениеДня. Если дата не задана, то считается, что задание не выполнялось ни разу и проверка этих условий не производится.
<ДатаЗавершенияПоследнегоЗапуска> (необязательный)

Тип: Дата.
Дата завершения последнего запуска регламентного задания. Если дата задана, то используется для проверки условия ПаузаПовтора. Если дата не задана, то считается, что задание ни разу не завершалось, и проверка этого условия не производится.
Возвращаемое значение:

Тип: Булево.

Описание:

Проверяет, выполняется ли расписание для заданной даты.

Доступность:

Сервер, толстый клиент, внешнее соединение.

Но тут есть нюансы:
с первым параметром вроде все ясно
а вот со вторым и третьим - уже так совсем.
:)
19. Юрий Осипов (yuraos) 27.11.13 16:44
(15) i_lo,
если открыть базу в руле скуля,
то можно найти табличку _ScheduledJobs (см. скриншот),
которая как я могу судить имеет отношение к нашему предмету.
Прикрепленные файлы:
20. Юрий Осипов (yuraos) 27.11.13 16:47
(19)
надо полагать,
что "ДатаПоследнегоВыполнения" - это поле "_FinishTime"
21. Сергей Старых (tormozit) 27.11.13 17:16
(20) Нет. Хранятся обе даты. Про вторую (дату окончания запуска) обычно не упоминают, т.к. она реже играет роль. Но строго говоря обе этих даты очищаются при записи регламентного задания и обе же используются планировщиком при проверке "надо ли запустить фоновое задание?".
22. Юрий Осипов (yuraos) 27.11.13 17:18
Резюмируя (7)(10)(13) с учетом (19)
можно ли считать верным утверждение:

что решение о запуске задания принимается только в зависимости
от значений полей "_StartTime" и "_FinishTime"
и никак не зависит от предыстории выполнения задания ???
---
так сказать запуск решения является своего рода "марковским" процессом.
23. Сергей Старых (tormozit) 27.11.13 17:48
(22) Ну я уже вроде отвечал на этот вопрос (10) и пояснил в (21). История тут не используется.
24. Александр Лукин (i_lo) 27.11.13 19:29
(18) yuraos, я соглашусь, что у меня простейший метод проверки, должно ли данное РЗ выполняться. Он работает только если РЗ начинаются утром и заканчиваются вечером. Для более универсального алгоритма правильнее было бы использовать указанный метод. Но для моего случая этого было достаточно ).
Что касается дат и предистории. Согласен, что менеджер РЗ работает по датам. Но именно в описанном в статье случае, подвисания РЗ после перезапуска сервера 1С, значение ПоследнегоЗадания оказывается Неопределенным. И после перезаписи, менеджер РЗ нормально продолжает работу. Исправление ситуации на лету!
Ещё и надеюсь, что разработчики платформы разберутся и исправят ситуацию в новых релизах )...
25. Максим Мельников (maclen_mmv) 27.11.13 19:33
Очень интересная тема...
26. Юрий Осипов (yuraos) 02.12.13 17:38
(24) i_lo,

Ещё и надеюсь, что разработчики платформы разберутся и исправят ситуацию в новых релизах


НУ ТЫ БЛИН И ОПТИМИСТ!!!!!
27. Юрий Осипов (yuraos) 02.12.13 17:40
(26)
ДА У НИХ ДЛЯ КАЖДОГО РЕЛИЗА ПЛАТФОРМЫ 8.3
ПРЕДУСМОТРЕН СВОЙ РЕЖИМ СОВМЕСТИМОСТИ!!!
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа