Обслуговування фонових завдань на великому сайті


49

Ми маємо справу з цікавою проблемою на StackOverflow.

У нас є ціла купа маленьких завдань, які повинні швидко виконуватись. Приклад - оновлення списків "Пов'язані запитання". Що ми робили раніше - це повернути ці завдання на завантаження сторінок деяких користувачів.

Це ніколи не було ідеальним, але це було не дуже помітно. Тепер, коли SO пройшов знак питання на 1 000 000, ці нещасні користувачі починають це відчувати.

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

1. У IIS як користувацька нитка / пул для роботи в черзі

В основному ми створюємо декілька (не- ThreadPool , щоб не заважати IIS), і надаємо їм служби деякі колекції, в які ми втягуємо Funcs .

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

Ми також отримуємо доступ до всього нашого загального коду.

Зрозуміло, що ми не повинні використовувати фонові нитки. Заперечення, про які я знаю, зосереджені навколо голодуючих IIS (якщо ви використовуєте ThreadPool) і потоки відмирають випадковим чином (через переробку AppPool).

У нас є існуюча інфраструктура, щоб зробити випадкову смерть потоку не проблемою (можливо, в основному виявити завдання було відмовлено), і обмеження кількості потоків (і використання потоків, що не є ThreadPool) теж не є складним.

Чи пропускаю я якісь інші заперечення щодо об'єднання потоків потоків / черг роботи IIS?

Переміщено до StackOverflow , оскільки тут насправді не вирішено.

2. Як послуга

Або якесь стороннє рішення, або ж на замовлення.

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

Професіонал полягає в тому, що це "правильний шлях" для цього.

Мінуси полягають у тому, що ми або дуже обмежені в тому, що можемо робити, або нам доведеться розробити деяку систему для синхронізації цієї служби з нашою базою кодів. Нам також потрібно буде якось підключити весь наш моніторинг та помилки реєстрації помилок, які ми отримуємо безкоштовно за допомогою опції "В IIS".

Чи є якісь інші переваги чи проблеми з підходом до обслуговування?

Коротше кажучи, чи є небачені та непереборні проблеми, які роблять підхід №1 непрацездатним, і якщо так, чи є якісні сторонні послуги, ми повинні розглянути підхід №2?


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

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

7
Я не розумію, чому це не в StackOverflow. Це технічний компроміс, а не суб'єктивна оцінка. Ви просите проаналізувати різні підходи - це все об'єктивно. Тільки коли аналіз уточнив, що саме є компромісами, чи є суб'єктивність щодо нього, і наскільки я бачу, ваше питання не є: "що мені слід зробити більш важливим, моїм часом та ресурсами сервера, чи моїм часом користувача?" ' чи щось подібне.
Жорен

@Kevin Montrose - з ваших коментарів здається, що ви робите різницю між "потрібно скоро зробити-ish" і "планується з інтервалом". Чи можете ви детальніше пояснити, чому це два різних фонових завдання, які потребують іншого шаблону / інфраструктури?
Портман

@Portman - Принципова відмінність полягає в тому, що "скоро-іш" завдання не можна виконувати спекулятивно, нам дійсно потрібно чекати, поки ми знаємо, що їх потрібно виконати. Деякі зворотні підрахунки конвертів показують, що якби ми перенесли запити "Пов’язані запитання" (лише один із багатьох) на "тупу" вкладку кронів, це займе бл. тиждень суцільного виконання для опрацювання всіх питань. Як правило, ми також хотіли б, щоб вони виконувались якомога швидше (не впливаючи на досвід користувача), тоді як наші інтервальні завдання можна отримати, виконуючись не частіше одного разу за 5 хвилин (і зазвичай набагато рідше).
Кевін Монтроуз

Відповіді:


17

Кілька тижнів тому я задав подібне запитання щодо SO. Що стосується горіхової оболонки, то я вже деякий час підходив до розробки служби Windows. Я б використовував NServiceBus (по суті, MSMQ під обкладинками) для маршальських запитів з мого веб-додатка до моєї служби. Раніше я використовував WCF, але правильна робота розподіленої транзакції над WCF завжди здавалася болем у дупі. NServiceBus зробив свою справу, я міг вводити дані та створювати завдання в транзакції, і не хвилюватися, чи працював мій сервіс у той час. Як простий приклад, якби мені коли-небудь потрібно було надіслати електронний лист (наприклад, електронний лист для реєстрації), я створив обліковий запис користувача та відключив сигнал до моєї служби Windows (щоб надіслати електронний лист) під час транзакції. Обробник повідомлень на стороні обслуговування підніме повідомлення та обробить його відповідно.

З моменту випуску ASP .NET 4.0 та AppFabric, існує ряд життєздатних альтернатив вищевказаному механізму. Посилаючись на питання, яке я згадав вище, тепер у нас є AppInitialize AppFabric (через net.pipe), а також функція автоматичного запуску ASP .NET 4.0, що робить розробку служб Windows як веб-додатків життєздатною альтернативою. Я почав це робити зараз з кількох причин (найбільша - розгортання - це не біль у дупі):

  1. Ви можете розробити веб-інтерфейс через свій сервіс (оскільки він працює як веб-додаток). Це надзвичайно корисно, щоб побачити, що відбувається під час виконання.
  2. Ваша модель розгортання веб-додатків буде працювати для вашої програми обслуговування.
  3. IIS надає кілька акуратних функцій для усунення несправностей додатків (схожих в деяких відношеннях до служби Windows).
  4. Веб-розробники дуже добре знайомі з розробкою веб-додатків (природно), більшість не знають багато про найкращу практику при розробці служби Windows.
  5. Він надає ряд варіантів розкриття API для інших програм, які споживають.

Якщо ви підете цим маршрутом (вибачте мене за копіювання та вставку з мого оригінального допису), я б точно подумав про використання фонової логіки в окремому веб-додатку. Для цього є ряд причин:

  1. Безпека . Для інтерфейсу користувача може бути інша модель захисту, яка відображає інформацію про запущені фонові процеси. Я не хотів би відкривати цей інтерфейс іншим, окрім команди ops. Також веб-додаток може працювати як інший користувач, який має підвищений набір дозволів.
  2. Технічне обслуговування . Було б чудово мати можливість розгортати зміни в додатку, що розміщує фонові процеси, не впливаючи на користування веб-сайтом на передній частині.
  3. Продуктивність . Якщо програма застосована окремо від основного запиту сайту, що обробляє запити, це означає, що фонові потоки не зменшать можливість IIS обробляти чергу вхідних запитів. Крім того, додаток, що обробляє фонові завдання, може бути розгорнутий на окремий сервер, якщо потрібно.

Це повертається до аспекту марширування. WCF, NServiceBus / RabbitMQ / ActiveMQ тощо, ванільний MSMQ, RESTful API (думаю, MVC) - це всі варіанти. Якщо ви використовуєте Windows Workflow 4.0, ви можете відкрити кінцеву точку хоста, яку може використовувати ваш веб-додаток.

Підхід до веб-хостингу для сервісів для мене все ще досить новий, лише час покаже, чи це був правильний вибір. Поки що добре, хоча. До речі, якщо ви не хочете користуватися AppFabric (я не зміг, оскільки з якихось химерних причин веб-версія Windows Server не підтримується), можливість автозапуску, згадана у публікації Гу, працює чудово. Проте тримайтеся подалі від файлу applicationhost.config, все, що є на цій посаді, можна встановити через консоль IIS (Редактор конфігурації на рівні основного сервера).

Примітка. Спочатку я опублікував ще кілька посилань у цьому повідомленні, але на жаль, це моє перше повідомлення до цього обміну, і підтримується лише одне посилання! В основному було ще два, щоб отримати їх від Google "Смерть службам Windows ... Довго Live AppFabric!" та "автозапуск-asp-net-програми". Вибач за те.


Основна ідея використання окремого веб-сайту як сервісу - інтригуюча, яку я не розглядав ...
Кевін Монтроуз

Роланд, я, можливо, щось тут не вистачає, але, здається, ти кажеш, що ти спілкувався зі службою Windows зсередини вашого обробника NServiceBus, сервіс потім надсилає електронний лист. Якщо я маю рацію, чи можу я запитати, чому ви просто не надсилаєте електронний лист від обробника повідомлень NServiceBus, що було б дуже легко розробити, протестувати та розгорнути?
Шон Кірон

Веб-сайт надсилає повідомлення службі Windows. Обробник повідомлень Windows Service NServiceBus приймає повідомлення та надсилає повідомлення. По суті, це те саме, що описаний вами процес.
Роланд

22

Насправді в Windows існує третій спосіб запуску фонових служб, і це дуже часто в світі UNIX. Третій спосіб - це CRONробота, яка керує частиною вашої інфраструктури. У Windows це відоме як task schedulerі є дуже поширеним для роботи коду на плановій основі. Для цього ви створили б додаток командного рядка, який виконується за попередньо визначеним графіком. Перевагою цього є те, що вам не доведеться турбуватися, якщо процес залишається і працює як сервіс, адже якщо він з певних причин вийде з ладу, він просто запуститься наступного разу.

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

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

Безсоромне просування, але це мій проект, і я лише коротко детально розказав, чому я створив проект: http://github.com/managedfusion/fluentcassandra/


2
Я роблю це за допомогою мого спільного хостингу, оскільки у мене немає доступу до оболонки. Напишіть сторінку PHP, яка робить щось важливе, а потім отримайте завдання cron, яке періодично завантажує сторінку, використовуючи wget або lynx. Це звучить як саме той тип речі, який би працював у цьому випадку і був надзвичайно простим, навряд чи вимагав би змінити спосіб, який зараз роблять.
Рікет

Яке просте рішення. Це породило ідеї для мого власного проекту, які я ще навіть не розглядав. Крім того, ви маєте повний доступ до наявної кодової бази. Просто додайте проект до консолі та посилайтеся на існуючі проекти.
Тім Мерфі

10

Веб-додаток Cron +

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

Ось як це працює:

  1. Створіть контролер / дію у своєму веб-додатку для обробки запланованих фонових завдань. За умовами, я зазвичай називаю свою http://mydomain.com/system/cron.
  2. Для безпеки цю дію слід заблокувати лише для автентифікованих IP-адрес у локальній мережі.
  3. На відокремленій машині встановіть Wget і встановіть заплановану задачу, щоб wget забирав ресурс з кроку 1. Ви можете зробити завдання виконувати так часто, як вам потрібно (я зазвичай вибираю 30 секунд). Не забувайте передавати Wget відповідний аргумент cookie, щоб він перевіряв автентифікацію на ваш веб-додаток.
  4. Для надмірності ви також можете встановити другий розпланований wget на другій машині.

Ура! Тепер у вас є маршрут, який буде називатися кожні 30 секунд. І якщо на обробку запиту піде 5 хвилин, ніхто не буде хвилюватись, оскільки це не є частиною запиту сторінки користувача.

cronДія закінчується виглядає дуже просто: у нього є список методів для виконання на певній частоті. Коли надходить запит, він бачить, чи є метод, який потрібно виконати, і викликає відповідний метод. Це означає, що ви можете керувати розкладом у вашій базі даних , де, ймовірно, вже є безліч інших важливих даних конфігурації для вашого сайту.

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

Плюси і мінуси

Плюси
  • Ви вже дуже добре пишете код ASP.NET MVC, тому це дозволяє записувати фонові завдання на тій самій платформі, в яку ви пишете іншу частину свого рішення.
  • Завдання виконуються в тому ж контексті, що і ваш веб-додаток, тож ви можете ділитися кешем та використовувати допоміжні методи, які вже існують.
  • Якщо ви отримали wget за допомогою URI, збалансованого навантаженням , то і ваші фонові завдання тепер також збалансовані навантаженням.
  • Одночасне розгортання - вам не доведеться турбуватися про синхронізацію веб-програми з логікою фонового завдання, оскільки всі вони в одному розгортанні.
Мінуси
  • Протягом багатьох років кілька людей говорили мені, що ця конструкція є "сильно пов'язаною", але при натисканні вони не змогли сформулювати, чому це погано.

Примітка. Якщо є якісь питання або проблеми, будь ласка, додайте коментар . Я радий деталізувати.


7

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

У мене також було заплановане завдання, яке відображає URL-адресу в додатку ASP.NET - це гідне рішення, але воно починає руйнуватись за хвилину, коли ви масштабуєте минулий 1 веб-сервер.

В даний час я використовую два різні методи, обидва використовують Quartz.NET, яка є чудовою маленькою бібліотекою. Перший - це Quartz.NET, який працює під час роботи з ASP.NET, він встановлюється в global.asax і працює кожні пару хвилин. Я використовую це для оновлення кешу ASP.NET поза діапазону, і це єдина причина, коли він запускається як частина ASP.NET.

Друга полягає в тому, що я написав бібліотеку, щоб обернути Quartz.NET під назвою DaemonMaster - це полегшує запуск DLL в каталог і запуск його в службі Windows. Я виявив, що це допомагає уникнути деяких дратівливих частин роботи зі службою Windows, а також очищає частину api Quartz.NET. Сервіси, що працюють через DaemonMaster, мають два різні смаки, перше - це завдання, які потрібно виконувати щовечора або щохвилини X. Інші завдання працюють з черги на основі даних, що надходять із програми ASP.NET. Додаток ASP.NET скидає об’єкти JSON на RabbitMQ, а служби опитують RabbitMQ, а потім обробляють дані.

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


6

Я зробив би це правильно, і запустив службу Windows, яка відслідковує "чергу". Я кажу "черга", тому що програмування w / MSMQ схоже на приклеювання гарячих покер у ваші очні яблука.

Я закохався у простоту Delayed :: Job in Rails, і щось подібне можна було б легко зробити в .NET.

В основному ви додаєте будь-який тип SomethingOperation(щось, що має Perform()метод). Потім просто серіалізуйте відповідні параметри, надайте йому пріоритет, якусь поведінку за замовчуванням, і повторіть їх у базі даних.

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


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

Так, це те саме рішення, що я використовував, проте я цілий об'єкт в базі даних серіалізував як двійковий і потім витягнув їх для виконання. Я використовував Кассандру в якості постійного планувальника зберігання та плану завдань як планувальник CRON для програми командного рядка, який би запускав і виконував завдання.
Нік Берарді

Ми почали, включивши у повідомлення простий фрагмент даних і закінчивши викидання всього об’єкта. Це все одно вийшло чудово. Я б розглядав поділ, оскільки він має і інші переваги.
Натан Палмер

@Kevin - якби у нас були люди з великою історією серіалізації ....
Marc Gravell

4

Ми були дуже задоволені службовою шиною / чергою повідомлень / підходом до обслуговування. Основна архітектура така.

Веб-сайт надсилає повідомлення в чергу

bus.Send(new ProjectApproved()); // returns immediately

Служба Windows отримує та обробляє повідомлення у свій час

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Do something "offline"
   }
}

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

Якщо ви не можете зберігати всі свої дані в повідомленні, ви завжди можете їх зберігати та отримувати пізніше. Я пропоную використовувати механізм зберігання документів, такий як: RavenDB або MongoDB, де дуже прямо вперед зберігати свої класи без змін.

Веб-сайт надсилає повідомлення в чергу

// Save your object
store.Save(completeProject);

// Send a message indicating its ready to be processed
bus.Send(new ProjectApproved() { ProjectId = completeProject.Id });

Служба Windows отримує та обробляє повідомлення у свій час

public class DoesSomethingAwesome : ConsumerOf<ProjectApproved>
{
   public void Consume(ProjectApproved Message)
   {
      // Retrieve your object back
      var completeProject = store.Get(Message.ProjectId);
   }
}

Для спрощення речей ми використовуємо: Rhino ESB та Topshelf . Конфігурація надзвичайно проста, і, можливо, це вимагає дуже мало часу для існуючої програми.


У будь-якому разі використання службової шини за допомогою CQRS - це завжди хороший спосіб покращити масштабованість
подумайте перед тим, як кодувати

3

Мені цікаво, чому поєднання двох не є життєздатним варіантом. Зараз ви запускаєте завдання на перегляді сторінок, коли якийсь нещасний сік застрягає, чекаючи 10 секунд, поки сторінка з’явиться. Принаймні, це моє розуміння вашого теперішнього методу.

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

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

#!/bin/bash
wget -O /dev/null http://stackoverflow.com/specially_crafted_url

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

Оновлення

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

wget -O /dev/null http://localhost/specially_crafted_url

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


Ми вже це робимо для всього, що працює з передбачуваними інтервалами, те, що нам залишається, - це речі, які не можна передбачити занадто далеко заздалегідь. Наприклад, "блок пов'язаних питань" оновлюється лише на питання, які переглядалися недавно. Списки з тегами питань також кешуються лише в тому випадку, якщо хтось поцікавився, щоб перевірити ці теги. Оскільки у нас понад мільйон запитань і наближаємось до 25k тегів, ми не можемо виконати всі пов'язані з цим завдання (і це лише 2 приклади) "на всякий випадок".
Кевін Монтроуз

Існують також проблеми балансу навантаження, оскільки SO розділений на декілька серверів. В основному, якщо ви переходите на stackoverflow.com, ви завжди потрапляєте на один і той же сервер. Підхід wget змусить нас перенести всі завдання на один сервер (або реально переробити налаштування балансування навантаження), що було б дуже боляче.
Кевін Монтроуз

Будь приємним, якби справи йшли через рівні проміжки часу, так? Я розумію, що ви говорите, але методологія, викладена вище (і я думаю, що згадується ще кількома людьми), не змінюється. Коли на переглядах сторінки написано "настав час запустити цю роботу", ви вставите завдання в чергу повідомлень. Довга фонова робота виконує завдання, які вона знайде. У цьому випадку завдання - це не що інше, як URL-адреси, які потрібно запитувати. hehe Ви, ймовірно, можете встановити це на спільному сервері 20 доларів на місяць, оскільки для його роботи не потрібна база вашого коду. Погляньте на Amazon SQS для зручного обслуговування повідомлень.
Мельсосон

Щодо питань балансу навантаження. Якщо є бажання - знайдеться можливість! Замість того, щоб робити запит на stackoverflow.com, ви можете випадково вдарити сервер, використовуючи його IP-адресу. Якщо балансир завантаження перевіряє файли cookie для подання запитів, ви можете підробити файли cookie. Якщо він перевіряє IP-адресу, ви, ймовірно, можете навіть підробити це (оскільки вас не хвилює відповідь сервера).
mellowsoon

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

2

Я думаю, що підхід із чистого сервісного підходу полягає в тому, що у вас код розсіяний у сервісі та далеко від основної програми.

Ось що ми зробили з великими фоновими не залежними від часу завданнями, що зберігає код разом і спрощує службу:

  1. Створіть чергу завдань (або в пам'яті, або в БД, незалежно від стійкості для типів завдань)
  2. Створіть веб-сервіс, який виконуватиме завдання з черги
  3. Досвідчений простий сервісний додаток, який викликає веб-службу через визначений інтервал, залишає всі складні речі (пошук роботи та виконання) веб-службі у вашій базовій кодовій базі.

Навіть простіше, просто зателефонуйте в консольний додаток і скористайтеся Планувальником завдань або VisualCron, щоб перетворити його на "послугу".


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

1

Мені сподобався TopShelf. Зберігає простоту, але все ж робити це належним чином, працюючи як сервіс Windows. В основному створіть консольний додаток, додайте близько 15-20 рядків коду, після чого він встановиться як сервіс.

http://code.google.com/p/topshelf/


1

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


1

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

  • Немає зовнішньої служби для моніторингу
  • Простота впровадження: відсутність перехресних процесів, не вдосконалений моніторинг робочих місць
  • Ви все ще знаходитесь у своєму IIS-процесі, тому ви можете виконувати всі звичні журнали та інше (не потрібно для декількох файлів журналу)
  • Значно спрощене розгортання (коли ви оновлюєте послугу, вам доведеться зупинити службу, скопіювати файли, запустити службу - це додатково до ваших звичайних оновлень коду веб-сайту)

На мою думку, рішення в IIS - це просто "наступний крок" від копіювання роботи до випадкових переглядів сторінок.


1

Реска приємна. Або навіть Kthxbye, якщо вам потрібно буде повідомити про отримане значення після його завершення.

Обидва базі Redis / Ruby.

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

Досить впевнений, що ти можеш уникнути набагато більше за набагато менше, якщо ти розробиш цю своєрідну роботу в окремому об'єкті, тим більше, що, здається, ти маєш справу з проблемами з ниткою. Обидва Resque і Kthxbye перемістити обробку, щоб окремі процеси , щоб дозволити OS впоратися з паралелізмом.

Resque

Ктхбі


Я повинен спробувати Kthxbye хоча б через велике ім'я!
Натан Палмер

дуже приголомшливий. наступним буде ORLY? бібліотека. ймовірно, для статистичного моніторингу якогось…;)
Лукас

0

Я б використовував службу WCF, розміщену WAS, слухаючи чергу черги MSMQ.

Професіонали

  • Увімкніть та забудьте повідомлення в одному напрямку із веб-програми

  • MSMQ / WCF дроселювання та повторення

  • Гарантована доставка; D

  • Управління мертвими літерами

  • Розподілена обробка

  • WAS / MSMQ активація

Кон

  • MSMQ (він не мертвий ... Ще)

Особливості MSMQ у WCF робить використання MSMQ справді приємним. Так, ви будете кровоточити в конфігурації, але переваги будуть переважати жертву.


0

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


0

Ви можете переміщати роботу над фоновою ниткою (або багатьма фоновими нитками), використовуючи Rx і щось подібне:

var scheduler = new EventLoopScheduler( SchedulerThreadName );
_workToDo = new Subject<Action>();
var queueSubscription = _workToDo.ObserveOn( scheduler ).Subscribe( work => work() );
_cleanup = new CompositeDisposable( queueSubscription, scheduler );

Використовувати:

var work = () => { ... };
_workToDo.OnNext( work ); // Can also put on error / on complete in here

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

Ви можете керувати розміром пулу потоків тощо, написавши спеціальний планувальник замість використання EventLoopScheduler (який запускає один потік).


0

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

Перевага полягає в тому, що виконувана робота не пов'язана з хроном або графіком. У мене є процес процес, який працює щосекунди, але буде чекати довше і довше між початком нової роботи, залежно від того, чи мала вона робота. Крім того, з його допомогою можна діяти розумно на основі результату. Помилка 500? Ви отримали дійсно велику затримку? Робіть щось інше. Повідомте іншу послугу. І т.д.

І ця ж система працює на unix, з незначними модифікаціями.


0

Я не маю для вас відповіді, але проблема задзвонила - я пам'ятаю, як деякі випадкові хлопці один раз обговорювали це на подкасті .

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

Етвуд: Так.

Спольський: Це справедлива характеристика? Кожен веб-сайт має деякі завдання, які ви не хочете виконувати під час завантаження веб-сторінки, але ви хочете виконати з певним повторенням.

Етвуд: Я. Фонові завдання, щось таке.

Спольський: Я, так що ви зрозуміли?

Етвуд: Ну, я спочатку запитав у Twitter, бо просто хотів чогось легкого ваги. Мені дуже не хотілося, як писати сервіс Windows. Я відчував, що це було поза кодом групи. Плюс код, який насправді робить роботу, є насправді веб-сторінкою, тому що для мене це логічна одиниця роботи на веб-сайті - це веб-сторінка. Таким чином, це насправді так, як ми передзвонюємось на веб-сайт, це просто як ще один запит на веб-сайті, тому я розглядав це як щось, що повинно залишатися в черзі, і маленький підхід, який ми придумали, який був рекомендований мені в Twitter по суті було щось додати до кешу програми з фіксованим терміном дії, тоді у вас є зворотній дзвінок, тому коли закінчується термін, він викликає певну функцію, яка виконує роботу, потім ви додаєте його назад у кеш із тим самим терміном дії.


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

@Kevin Montrose, я благаю тут повне незнання домену. Чи можете ви пояснити, чому секретна веб-сторінка виконує цю роботу (можливо, у невеликих одиницях) і викликається освіжаючою роботою на сторінці / cron десь ще? Я не сумніваюся, що ви праві, але я хотів би вчитися.
Відмінна думка

Ваша спеціальна пропозиція (термін дії кешу) не масштабується, оскільки всі закінчення кешу (в ASP.NET) мають один потік (це розумний злом для менших сайтів, як це було раніше). Завдання Cron не масштабується, тому що ми переросли один сервер (SO зараз 3, і все ще зростає), і будь-яке завдання cron буде вражати один сервер (принаймні, змінити інваріант було б дуже болісно з нашими навантаженнями- налаштування балансу). Завдання Cron також повинно виконуватись дуже часто, оскільки ці завдання повторюються в порядку хвилин.
Кевін Монтроуз

Варто зауважити, що ми використовуємо графік "стилю крона" для менш часто виконуваного, фіксованого інтервалу, завдань, таких як грантові значки та щоденні повідомлення електронною поштою.
Кевін Монтроуз

0

Черга завдань Java API Огляд

Концепції задач
У фоновій обробці програми App Engine завданням є повний опис невеликої одиниці роботи. Цей опис складається з двох частин:

  • Корисне навантаження даних, яке параметризує завдання.
  • Код, який реалізує завдання.

Завдання як офлайн веб-гачки
На щастя, Інтернет пропонує таке рішення вже у вигляді HTTP-запиту та його відповіді. Корисне навантаження даних - це вміст запиту HTTP, такий як змінні веб-форми, XML, JSON або закодовані двійкові дані. Кодова посилання - сама URL-адреса; власне код є будь-якою логікою, яку виконує сервер під час підготовки відповіді.


Я не пропоную використовувати апрі чергу GAE api, але слідкую за їх моделлю. Вони деякий час продумали і написали його реалізацію.
antony.trupe

0

Зробіть обидва

Додайте необов'язковий параметр до шляху запитання, який виконує роботу, яку ви зараз переносите на запити користувачів:

Обслуговування фонових завдань на великому сайті

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

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

Використовуйте URL-адреси сторінок з розробленого журналу для виклику "додаткової" версії URL-адреси на localhost з об'єктом webclient.

Додайте код, щоб переключити файли в кінці кожного періоду журналу або перезапустити процес кожного періоду журналу.

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