Найкращий спосіб виконання запланованих завдань [закрито]


229

Сьогодні ми створили консольний додаток для виконання запланованих завдань для нашого веб-сайту ASP.NET. Але я думаю, що такий підхід є дещо схильним до помилок і його важко підтримувати. Як виконати заплановане завдання (у середовищі Windows / IIS / ASP.NET)

Оновлення:

Приклади завдань:

  • Надсилання електронної пошти з черги електронної пошти в базі даних
  • Видалення застарілих об'єктів із бази даних
  • Отримання статистики з Google AdWords та заповнення таблиці в базі даних.

Що є прикладом завдань, які ви виконуєте?
JeffO

4
Вам потрібно перевірити atrigger.com
Куша

Якщо у вас є Plesk, ви можете написати vbs і надіслати
HasanG

Відповіді:


74

Усі мої завдання (які потрібно запланувати) для веб-сайту зберігаються в межах веб-сайту та дзвонять із спеціальної сторінки. Потім я написав просту службу Windows, яка закликає цю сторінку так часто. Після запуску сторінки вона повертає значення. Якщо я знаю, що ще потрібно виконати роботу, я запускаю сторінку знову, одразу, інакше я запускаю її за короткий час. Це справді добре працювало для мене і зберігає всю логіку мого завдання з веб-кодом. Перш ніж писати просту службу Windows, я використовував планувальник Windows, щоб дзвонити на сторінку кожні х хвилин.

Ще одним зручним способом цього є використання служби моніторингу, наприклад Pingdom . Наведіть їхню http-перевірку на сторінку, на якій працює ваш код послуги. Попросіть результати повернення сторінки, які потім можуть бути використані для запуску Pingdom для надсилання сповіщень, коли щось не в порядку.


3
Це рішення, з яким я закінчився. Замість користувацького веб-сервісу я використовую планувальник windows + curl. Яка вигода від використання послуги Windows.
Нільс Босма

16
Ви подивилися на техніку терміну дії пункту кешу? Я думаю, ви побачите, що це набагато більш ідеальна реалізація планової послуги: codeproject.com/KB/aspnet/ASPNETService.aspx
Річард Клейтон

10
Що зупинити зловмисного користувача (або павука пошукової системи), який дзвонить на цю сторінку, і тим самим змушує запускати заплановані завдання?
UpTheCreek

8
Ви можете зупинити зловмисні дзвінки, зберігаючи статичну часову позначку у веб-додатку та виконуючись лише в тому випадку, якщо часова марка не встановлена ​​(перший дзвінок) або минув правильний час з моменту останнього дзвінка.
Роб Кент

5
Я припиняю зловмисні дзвінки на свій URL, перевіряючи, чи є ip-адреса внутрішньою чи ні. Він нічого не повертає і нічого не робить, якщо він не є внутрішнім для нашої організації.
user1408767

128

Цей прийом Джеффа Етвуда для Stackoverflow - це найпростіший метод, який я натрапив. Він спирається на вбудований механізм зворотного виклику "елемент кеш-пам'яті" в кеш-систему ASP.NET

Оновлення: Stackoverflow переріс цей метод. Він працює лише під час роботи веб-сайту, але це дуже проста техніка, яка корисна багатьом людям.

Також перевірте Quartz.NET


12
Отже, що станеться, якщо програма не працює, але заплановане завдання має відбутися?
MichaelGG

2
Це також може уповільнити користувацький досвід, якщо завдання запустить цей час. Я вважаю за краще, щоб користувач не породив мені завдання / завдання.
Брецький

5
Це страшно як пекло! Що-небудь може призвести до того, що програма перестане працювати, і вона, ймовірно, перезапуститься лише після наступного запиту користувача. У цей час ваші завдання не працюють!
teedyay

43
Щось я сьогодні помітив у коментарях до початкової публікації в блозі: No, we’ve switched to a dedicated task. We definitely outgrew this technique. I do think it’s fine for small sites though!- Джефф Етвуд
Джоел Коухорн

3
-1 У цьому великий підхід. Кожен раз, коли програма повторно переробляється, запускається подія "CacheItemRemoved", і ваше заплановане завдання запуститься. На виробничих майданчиках це може траплятися кілька разів на день. Не так добре, якщо ви хочете, щоб завдання виконували щотижня.
Стівен де Салас

30

Створіть власну службу Windows .

У мене були деякі критичні завдання, встановлені як додатки для запланованих консолей, і мені було важко підтримувати. Я створив службу Windows із серцебиттям, яка перевірятиме розклад у моїй БД кожні пару хвилин. Це відпрацьовано дуже добре.

Сказавши це, я все ще використовую заплановані програми консолі для більшості некритичних завдань технічного обслуговування. Якщо він не зламався, не виправляйте.


7
FYI посилання тепер мертва.
Чарльз Бернс

1
@CharlesBurns, ви завжди можете переглядати мертві посилання з archive.org: web.archive.org/web/20090919131944/http://www.dotheweb.net/…
Микола Костов

17

Я вважаю, що це легко для всіх залучених:

  • Створіть метод веб-сервісу, наприклад DoSuchAndSuchProcess
  • Створіть консольний додаток, який викликає цей веб-метод.
  • Сплануйте консольний додаток у планувальнику завдань.

Використовуючи цю методологію, вся бізнес-логіка міститься у вашому веб-додатку, але ви маєте надійність менеджера завдань Windows або будь-якого іншого комерційного менеджера завдань, щоб розпочати його та записати будь-яку інформацію про повернення, наприклад, звіт про виконання. Використання веб-сервісу замість публікації на сторінці має певну перевагу, оскільки простіше отримати дані про повернення з веб-служби.


10

Навіщо винаходити колесо, використовуйте клас Threading та Timer.

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }

7
Вам не потрібно
зароджувати

4
Я теж не думаю, що це ідеальне рішення.
Ідан Шехтер

12
@IdanShechter було б добре сказати причину, чому ви вважаєте це не ідеальним рішенням
Ому,

2
Нитка може бути проблематичною, оскільки це не HttpRequest, деякі дані, що стосуються HttpRequest, можуть бути нульовими. Наприклад, HttpRequest .ApplicationPath. Якщо завдання написано правильно, воно спрацює. Інша проблема - перезапуск пулу додатків. Якщо пул перезапускається занадто часто (витік пам'яті ...), працівник ніколи не запускається.
Томаш Кубес

2
Якщо у вас працює кілька екземплярів (наприклад, балансування навантаження) - можливо, ви не хотіли б цього рішення (кілька завдань роблять те саме)
Іллідан

8

Використовуйте Планувальник Windows для запуску веб-сторінки.

Щоб запобігти запуску зловмисних користувачів або павуків пошукової системи, під час налаштування запланованого завдання просто зателефонуйте на веб-сторінку за допомогою рядка запитів, тобто: mypage.aspx? From = rasporedtask

Потім у завантаженні сторінки просто використовуйте умову: if (Request.Querystring ["from"] == "rasporedtask") {// Executetask}

Таким чином жоден павук пошукової системи чи зловмисний користувач не зможе виконати заплановане завдання.


5
А ще краще використовувати алгоритм солоного хешування, який насправді перевіряє рядок запитів з трохи більшою безпекою, ніж магічна фраза. Req буде чимось на зразок mypage.aspx? Salt = foo & hash = 1223523jbhdgu13t1. Вам просто потрібно мати однаковий алгоритм хешування на сервері та клієнті. Також додайте жорсткий ліміт на сервері; збережіть, коли він був виконаний, і не дозволяйте виконувати занадто швидко. Я, можливо, був параноїком.
Ненотлеп

14
Ще безпечніше використовуйте програму Windows Scheduler для запуску веб-сторінки, яка перевіряє, чи надходить запит від самого сервера: Request.IsLocal>> тільки заплановані завдання може виконувати тільки сам сервер, ніхто інший.
Конспірація

Чи маєте ви більше досвіду свого підходу? Я збирався розробити подібний тип сервісу нашого додатку, і тепер я не можу визначитися, чи краще викликати сторінку із запланованим завданням чи кроном, чи використовувати кеш-систему.
JayDee


3

Крім того, якщо ваша програма використовує SQL SERVER, ви можете використовувати агент SQL для планування своїх завдань. Тут ми зазвичай ставимо повторюваний код, який керується даними (нагадування електронної пошти, планове обслуговування, очищення тощо). Відмінна особливість, вбудована в Агент SQL, - це параметри сповіщення про помилки, які можуть попередити вас, якщо критична задача не вдасться.


2

Я не впевнений, про які заплановані завдання ви маєте на увазі. Якщо ви маєте на увазі такі речі, як "щогодини, оновіть foo.xml", виконайте завдання типу "Заплановані завдання Windows". (Команда "at" або через контролер.) Попросіть її або запустити консольну програму, або запросити спеціальну сторінку, яка починає процес.

Редагувати: Додам, це нормальний спосіб, щоб ваш додаток IIS також працював у запланованих точках. Тож припустимо, що ви хочете перевіряти свою БД кожні 30 хвилин та надсилати нагадування користувачам про деякі дані, ви можете використовувати заплановані завдання, щоб запитувати цю сторінку, і, отже, отримувати обробку речей IIS.

Якщо ваші потреби складніші, ви можете створити службу Windows і запустити цикл, щоб виконувати будь-яку обробку, яка вам потрібна. Це також має перевагу відокремлення коду для масштабування чи управління. З іншого боку, вам потрібно мати справу з сервісами Windows.


2

Якщо у вас є сервер, ви повинні використовувати планувальник завдань Windows. Використовувати AT /? з командного рядка, щоб побачити параметри.

В іншому випадку з веб-середовища, можливо, вам доведеться зробити щось неприємне, як створити іншу машину для запитів на певну сторінку з тимчасовим інтервалом.


2

Я успішно використовував Abidar в проекті ASP.NET (ось деяка довідкова інформація ).

Єдина проблема цього методу полягає в тому, що завдання не виконуватимуться, якщо веб-додаток ASP.NET не буде завантажено з пам'яті (тобто через низьке використання). Одне, що я спробував, - це створити завдання натискати на веб-додаток кожні 5 хвилин, зберігаючи його живим, але це, здається, не працює надійно, тому зараз я використовую для цього планувальник Windows та базовий консольний додаток.

Ідеальним рішенням є створення служби Windows, хоча це може бути неможливим (наприклад, якщо ви використовуєте спільне середовище хостингу). Це також полегшує справи з точки зору технічного обслуговування, щоб зберігати речі у веб-програмі.


1

Ось ще один спосіб:

1) Створіть веб-скрипт "серцебиття", який відповідає за запуск завдань, якщо вони ДУМОВІ або прострочені для запуску.

2) Створіть десь запланований процес (бажано на тому ж веб-сервері), який потрапляє на веб-скрипт і змушує його працювати через регулярний інтервал. (наприклад, завдання розкладу Windows, яке тихо запускає сценарій теплового биття за допомогою IE або whathaveyou)

Те, що код завдання міститься у веб-скрипті, суто задля збереження коду в базі кодів веб-додатків (припущення, що обидва залежать один від одного), що було б легше керувати веб-розробникам. .

Альтернативний підхід полягає у створенні виконуваного сценарію / програми сервера, який виконує всю роботу розкладу сам і запускає сам виконуваний файл як заплановане завдання. Це може забезпечити фундаментальну розв'язку між веб-додатком та запланованим завданням. Отже, якщо вам потрібні заплановані завдання, навіть якщо веб-додаток / база даних може бути недоступною або недоступною, вам слід скористатися таким підходом.


1
@Matias, чому б просто не запланований процес зробити справжню роботу замість цього?
ЛукаХ

1

Ви можете легко створити службу Windows, яка запускає код з інтервалом, використовуючи метод 'ThreadPool.RegisterWaitForSingleObject'. Це дуже гладко і досить легко налаштувати. Цей метод є більш спрощеним підходом, ніж використовувати будь-який таймер у рамках.

Перегляньте посилання нижче для отримання додаткової інформації:

Запуск періодичного процесу в .NET за допомогою сервісу Windows:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html


0

Ми також використовуємо консольні програми. Якщо ви використовуєте такі засоби реєстрації, як Log4net, ви можете належним чином контролювати їх виконання. Крім того, я не впевнений, чим їх складніше підтримувати, ніж веб-сторінку, якщо ви обмінюєтесь цими одними і тими ж бібліотеками коду між цими двома, якщо вони правильно розроблені.

Якщо ви проти того, щоб ці завдання виконувались вчасно, у вашому адміністративному розділі веб-сайту може бути веб-сторінка, яка виконує функції черги. Користувач ставить запит на запуск завдання, він, в свою чергу, вставляє порожню запис дати мітки в таблицю MyProcessQueue, і ваше заплановане завдання перевіряє кожні X хв на нову запис у MyProcessQueue. Таким чином, він працює лише тоді, коли клієнт хоче, щоб він працював.

Сподіваюсь, ці пропозиції допоможуть.


0

Одним із варіантів було б налаштувати службу Windows і дозволити їй викликати заплановане завдання.

У winforms, який я використовував Таймери, не думаю, що це буде добре працювати в ASP.NET


-1

Нова бібліотека класів планувальників завдань для .NET

Примітка. Оскільки ця бібліотека була створена, Microsoft представила новий планувальник завдань (Планувальник завдань 2.0) для Windows Vista. Ця бібліотека є обгорткою інтерфейсу Task Scheduler 1.0, який все ще доступний у Vista та сумісний з Windows XP, Windows Server 2003 та Windows 2000.

http://www.codeproject.com/KB/cs/tsnewlib.aspx


Видаліть, будь ласка. На це відповідь нижче. Дублікат
Fandango68
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.