Обслуживание фоновых задач на большом сайте

Обслуживание фоновых задач на большом сайте
Обслуживание фоновых задач на большом сайте - afgprogrammer @ Unsplash

На StackOverflow мы столкнулись с интересной проблемой.

У нас есть целая куча маленьких задач, которые "должны быть выполнены в ближайшее время". Например, обновление списков "Связанные вопросы". В прошлом мы выполняли эти задачи в виде "свиньи" при загрузке страниц некоторых пользователей.

Это не было идеальным, но это было не очень заметно. Теперь, когда SO перешагнул отметку в 1 000 000 вопросов, эти неудачливые пользователи начинают это ощущать.

Естественное решение - вытеснить эти задачи в фоновый режим. Есть два основных способа сделать это, которые я рассматриваю.

1. В IIS как пользовательский Thread-Pool/Work-Queue

По сути, мы запускаем несколько (не🔁 ThreadPool , чтобы не мешать IIS) потоков и заставляем их обслуживать некоторые коллекции, в которые мы пихаем Funcs .

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

Мы также получаем доступ ко всему нашему общему коду.

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

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

Am I missing any other objections to in IIS process thread-pooling/work-queues?

Перемещено в StackOverflow, так как здесь этот вопрос не рассматривался.

2. В качестве сервиса

Либо какое-то стороннее решение, либо собственное.

По сути, мы должны передать задачу через границу процесса какому-то сервису и просто забыть о ней. Предположительно, мы подключаем какой-то код или ограничиваемся сырым SQL + строка подключения.

Плюсом является то, что это "правильный способ" сделать это.

Минусы заключаются в том, что мы либо очень ограничены в своих возможностях, либо нам придется разработать какую-то систему для синхронизации этой службы с нашей кодовой базой. Также нам нужно будет как-то подключить мониторинг и регистрацию ошибок, которые мы получаем бесплатно при использовании опции "In IIS".

Есть ли еще какие-либо преимущества или проблемы с таким подходом к службе?

В двух словах, есть ли непредвиденные и непреодолимые проблемы, которые делают подход №1 неработоспособным, и если да, то есть ли хорошие сторонние сервисы, на которые мы должны обратить внимание для подхода №2?

Несколько недель назад я задал аналогичный вопрос на 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. Безопасность. Может быть другая модель безопасности для пользовательского интерфейса, отображающего информацию о запущенных фоновых процессах. Я бы не хотел раскрывать этот пользовательский интерфейс кому-либо еще, кроме операционной команды. Кроме того, веб-приложение может работать от имени другого пользователя с повышенным набором разрешений.
  2. Обслуживание. Было бы здорово иметь возможность развертывать изменения в приложении, в котором размещены фоновые процессы, не влияя на использование пользователем внешнего веб-сайта.
  3. Производительность. Отделение приложения от основного сайта, обрабатывающего запросы пользователей, означает, что фоновые потоки не уменьшат возможности IIS по обработке очереди входящих запросов. Кроме того, приложение, обрабатывающее фоновые задачи, при необходимости может быть развернуто на отдельном сервере.

Это возвращает нас к аспекту маршалинга. WCF, NServiceBus/RabbitMQ/ActiveMQ и т. д., vanilla MSMQ, RESTful API (думаю, MVC) — все это варианты. Если вы используете Windows Workflow 4.0, вы можете предоставить конечную точку хоста, которую может использовать ваше веб-приложение.

Подход к услугам веб-хостинга все еще довольно нов для меня, только время покажет, был ли это правильный выбор. Хотя пока все хорошо. Кстати, если вы не хотите использовать AppFabric (я не мог, потому что по какой-то странной причине Windows Server Web Edition не поддерживается), функция автозапуска, упомянутая в посте Гу, прекрасно работает. Однако держитесь подальше от файла applicationhost.config, все в этом посте можно настроить через консоль IIS (редактор конфигурации на уровне основного сервера).

Примечание: изначально я разместил еще несколько ссылок в этом сообщении, но, увы, это мой первый пост на эту биржу, и поддерживается только одна ссылка! По сути, было еще два других, чтобы заставить их Google «Смерть службам Windows ... Да здравствует AppFabric!» и «автозапуск приложений asp-net». Извини за это.


LetsCodeIt, 23 мая 2023 г., 10:11