В одно из прошлых статей Илья Голев уже писал о том, как мы настроили напоминания для себя о не запустившихся приложениях. Со временем мы осознали, что на самом деле это не совсем то, чего мы хотим. На самом деле мы хотим получать сообщения о том, что все незапущенные планировщиком приложения уже перезапущены автоматически и повода для беспокойства нет. Мы хотели помощника-планировщика.
Автоперезапуск приложений: Круг задач
После более детального обсуждения был обозначен круг задач, которые предстоит решить:
- Утилита должна перезапускать приложения, которые не запустил планировщик QlikView.
- Она должна уметь смотреть и анализировать цепочку перезагрузки планировщика QlikView – если не запустились приложения в цепочке выше – перезагрузка должна начинаться с места обрыва очереди перезагрузки и распространяться на все приложения ниже по цепочке.
- Перезагрузка приложений одного уровня иерархии в цепочке должна осуществляться параллельно.
- Должна быть возможность загрузки в несколько потоков – загрузка одной цепочки приложений не должна препятствовать загрузке другой цепочки приложений.
- При начале перезагрузки должна осуществляться проверка, не грузятся ли предложенные к перезагрузке приложения уже в параллельном потоке.
- После перезагрузки каждой ступени цепочки перезагрузки должен просматриваться лог перезагрузки на предмет ошибок – если есть ошибки в перезагрузке приложений – цепочка обрывается, дальше в работу вступаем мы.
- О результатах работы нам должно быть сообщено, сообщений может быть три типа:
- Все прошло успешно.
- Перезагрузка не начата, потому что приложение уже грузится в параллельном потоке.
- Перезагрузка остановлена, потому одна из ступеней выполнилась с ошибками.
Планировщик: Принцип работы
QlikView и PowerShell поделили между собой задачи следующим образом – QlikView считает данные, PowerShell на основе этих данных выполняет действия (классика – ведь QlikView всегда выдает данные, которые помогают в принятии решений, только тут место человека занял PowerShell).
Далее я постараюсь описать, как были решены все вышеописанные задачи.
Работа утилиты начинается с появлением флаг-файла – он создается вместе с отправкой нам сообщения о том, что что-то не запущено. Этот файл содержит наименование приложения, которое в нормальном режиме к этому времени уже должно быть запущено.
В первую очередь перезапускается приложение QlikView для анализа цепочки перезагрузки, его работа происходит в следующем порядке:
- забирает приложение, которое хочет быть перезапущенным;
- смотрит в планировщик QlikView и забирает оттуда цепочку перезагрузки, в которой участвует приложение инициатор, выстраивает иерархию перезагрузки:
- смотрит, что сегодня уже грузилось, а что – нет. При необходимости иерархия урезается – грузим только то, что еще не перезагружено;
- смотрит, не работает ли утилита в параллельном потоке и проверяет – вдруг предложенная к перезагрузке цепочка уже грузится? Если да – то цепочка снова обрезается до приложений, которые еще не грузятся.
- Финальный этап — создание файлов для дальнейшей работы PowerShell. Если в нашей цепочке перезагрузки еще остались приложения, QlikView распределяет их по ступеням перезагрузки и создает файл со списком приложений для каждой ступени. Если перезагружать нечего – создается стоп-флаг, который останавливает дальнейшую работу.
Теперь в работу включается Powershell.
В первую очередь, он смотрит, нет ли стоп-флага – если есть, то работа прекращается и нам летит сообщение что перезагружать то, собственно, ничего и не требуется. В случае его отсутствия – забирается цепочка перезагрузок и начинается перезагрузка каждой ступени по очереди.
На этом этапе очень важным требованием была параллельная загрузка приложений ступени, ведь если их грузить друг за другом, это непомерно удлиняет время перезагрузки. Например, у нас есть цепочка из 15 приложений, в которой 4-5 приложений грузятся одновременно. Если же их вытянуть в ряд, то это займет около 10 часов, что категорично нас не устраивает.
К счастью, если PowerShell дать список приложений для запуска в цикле For Each, то он все их и запустит одновременно, но как нам узнать что ВСЕ приложения ступени закончили перезагрузку? Для этого мы воспользовались пространством имен System.Diagnostics.
НА ЗАМЕТКУ! System.Diagnostics.process.id – id процесса QlikView, который выполняет перезагрузку приложения.
Мы решили собрать id всех процессов и просто ждать окончания их перезагрузки.
После того как мы дождались перезагрузки всех приложений цепочки, осталось проверить не выполнилась ли перезагрузка с ошибкой (для этого анализируем лог QlikView). Если ошибки есть – нам летит сообщение, что перезагрузка остановлена, и список приложений, перезапущенных с ошибкой. Если же все хорошо, то перезагрузка переходит на следующую ступень.
В итоге, если все прошло хорошо (о чем свидетельствует перезагрузка всех приложений иерархии перезагрузки), мы получаем сообщение, что все приложения перезагружены успешно.
Осталось сказать пару слов о распараллеливании потоков перезагрузки – в утилиту зашита возможность параллельной загрузки нескольких цепочек приложений и при перезагрузке происходят соответствующие действия: проверка на то, не грузится ли уже приложение в параллельной цепочке (о которой говорилось выше) и, собственно, создание списка приложений, которые грузятся:
Саму функцию сравнения списков мы предоставили QlikView, т.к. он для этого лучший инструмент (по сути, это сравнение двух таблиц и удаление одной из строк, которые есть в другой).
Последний вопрос – а умеет ли планировщик Windows запускать несколько экземпляров одной и той же задачи параллельно? Как оказалось – да:
Коллеги, на этом сегодня все! Задавайте вопросы, делитесь своими идеями!
Свежие комментарии