internet-logo41

Выполнение периодических фоновых задач на сервере

Допустим, нам нужно, чтобы определенная задача (функция нашего проекта) выполнялась на сервере периодически и фоново. Например, надо чтобы ночью собиралась статистика и отправлялась на веб-сайт, или чтобы клиентам рассылались письма с изменениями в их заказах, или чтобы каждые несколько часов обновлялись определенные данные в базе данных.

Какие основные варианты у нас имеются?
1) Написать простое GUI-приложение которое будет запущено на сервере и будет выполнять наши задачи.
2) Написать службу Windows (windows service), которая будет запускаться вместе с загрузкой Windows и так же выполнять наши задания.
3) Использовать Планировщик заданий windows (scheduled tasks) для запуска написанных нами приложений, которые будут выполнять что нужно.

Давайте разберем основные плюсы и минусы (на мой скромный субъективный взгляд) каждого подхода:

Итак, GUI приложение.
Плюсы:
+ Относительная простота реализации.
+ Возможность общения с пользователем (в случае фоновых задач такая возможность редко должна быть востребована, но мало ли).
Минусы:
- Приложение будет запущено только после того, как пользователь залогинится в Windows. Т.е., допустим, если сервер перезагрузится, то наше супер GUI-приложение не будет запущено. Это может быть очень критичным.
- Приложение можно случайно закрыть (администратор в суматохе кликнет по крестику или кнопке Close, а потом забудет запустить заново).
- Нужно будет самому писать простенький планировщик, который будет инициировать выполнение заданий. В принципе это просто (если не заморачиваться и допускать погрешности и сдвиги, типа перевода времени на зимний-летний режим), но не гибко, т.к. расписание будет либо жестко зашито внутри приложения, либо храниться в конфигурационном файле, и администратору сервера нужно будет знать, как править этот файл.

Идем дальше, служба Windows.
Плюсы:
+ Служба запускается, даже если пользователь не залогинен.
+ Можно запускать службу от имени любого пользователя (мне кажется это редко когда нужно, но, например, это может быть нужно для аутентификации в sql server под определенным пользователем, если sql server работает в режиме windows-аутентификации; или это может быть нужно для ограничения прав сервиса).
Минусы:
- Как и в случае с GUI-приложением, негибкость управления расписанием.
- Менее удобная отладка (отлаживать придется через Attach to process, а момент запуска службы вообще очень проблематично отлаживать).
- Несколько больше телодвижений с написанием службы (например нужно будет делать установщик службы).

Дальше, планировщик заданий:
Плюсы:
+ Задания могут выполняться, даже если пользователь не залогинен.
+ Гибкость настройки расписания и стандартность этого инструмента (т.е. администраторы с ним знакомы и умеют обращаться).
Минусы:
- Особо значимых минусов не вижу, но например - невозможность инициирования выполнения задач внешними событиями, т.е. нельзя ждать какого-то внешнего события и по нему начать выполнение задачи. Есть расписание - по нему и запускаемся.

Вот такие вот мысли.
Лично мне видится использование планировщика заданий достаточно простым, удобным и хорошим решением. Т.е. в solution можно добавить мелких консольных проектов (если их будет много, то чтобы они не мешались в solution explorer'е, их можно положить в отдельную папку), которые будут выполнять разные задачи. Ну и планировщик задач настроить на запуск этих маленьких приложений.