ASP.NET — запрос веб-страницы на распаковку файла на сервере

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

Каков хороший способ справиться с этим сценарием: выделить другой поток, чтобы позаботиться о распаковке файла, создать отдельную службу Windows, которая будет распаковывать файлы, или .... что?

Каковы плюсы и минусы выполнения этого через отдельный поток или оконную службу?


person dev.e.loper    schedule 14.05.2009    source источник
comment
Стоит перефразировать вопрос, чтобы отразить интересную часть. Самое главное не распаковка. Это как решить, выполнять ли асинхронную работу в процессе или вне процесса.   -  person Cheeso    schedule 15.05.2009


Ответы (4)


Преимущества отдельного процесса
Работа, выполняемая в отдельном процессе, может быть отделена во времени, а также физически и с точки зрения безопасности от потока страниц. Развязка во времени: если вы выберете, вы можете буферизовать запросы на распаковку до «позже», когда нагрузка снизится и когда у вас есть свободные циклы процессора для этого.

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

Однако я бы сказал, что это последнее преимущество полезно только в очень и очень крупномасштабных системах. В большинстве случаев у вас не будет такого объема транзакций, который выиграет от независимого уровня физического масштабирования. Это относится не только к вашей рабочей нагрузке, но и к 98% всех рабочих нагрузок. Принцип YAGNI применим и к масштабируемости.

Физическая развязка также позволяет независимо разрабатывать разрозненные рабочие нагрузки (поток страниц и распаковка zip). Другими словами, предположим, что рабочий элемент — это не просто «разархивировать файл», а что-то более сложное, с несколькими шагами и точками принятия решений на этом пути. Разработка рабочего процессора в отдельном процессе позволяет построить и протестировать поток страниц независимо от обработки рабочего элемента. Это может быть хорошим преимуществом, если они должны развиваться независимо.

Эта физическая развязка также удобна, если рабочие элементы будут поступать по разным каналам. Предположим, что веб-страница — не единственный способ получения рабочего элемента. Предположим, у вас есть узел ftp, веб-служба или контролируемый компьютером почтовый ящик, который также может получать рабочие элементы. В таких случаях имеет смысл физически отделить обработку рабочего элемента от обработки веб-страницы.

Наконец, эти вещи не связаны с безопасностью во время выполнения. В некоторых развертываниях серверов веб-приложений правила безопасности запрещают веб-серверу выполнять запись на диск — веб-серверы не имеют доступного для записи дискового хранилища. Отдельный асинхронный рабочий процесс может быть развернут в отдельной части сети с большим объемом памяти и, возможно, ограничен отдельным набором требований безопасности. Это может или не может быть применимо к вам.

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

Вы можете немного усложнить обработку рабочих элементов и при желании выполнять работу синхронно, когда zip-файл выглядит достаточно маленьким. Предположим, вы устанавливаете порог времени отклика в 4 секунды — выше этого вам нужна асинхронная рабочая нагрузка, ниже 4 секунд вы делаете это «встроенным». Конечно, вы никогда не знаете наверняка, сколько времени займет zip-файл, но вы можете установить хорошую эвристику, основанную на размере файла. Эта оптимизация доступна вам независимо от того, используете ли вы внешний процесс для асинхронной работы или отдельный поток, но, честно говоря, проще воспользоваться оптимизацией при использовании отдельного потока. Меньше дополнительной работы. Так что это преимущество многопоточного подхода.

Недифференцирующие элементы
Если вы решите использовать механизм опроса AJAX для уведомления о статусе рабочего элемента, он будет работать либо с отдельным процессом, либо с отдельным потоком. Я не знаю, как вы будете отслеживать рабочий элемент, но я полагаю, что когда конкретный рабочий элемент (zip-файл?) будет завершен, вы где-то обновите запись - файл в файловой системе, таблица в базе данных. . Это обновление происходит независимо от того, выполняется ли оно потоком в том же процессе или отдельным процессом (службой Windows). Таким образом, клиент AJAX, который опрашивает, в любом случае просто проверит таблицу db или файловую систему и получит уведомление о статусе рабочего элемента таким же образом, независимо от вашего решения по архитектуре.

Как принять решение
Теория интересна, но в конечном счете бесполезна, без реальных операционных ограничений.

Рабочая нагрузка является одним из ключевых элементов реального мира. Вы не сказали, насколько велики эти zip-файлы, но я предполагаю, что они «обычного размера». Что-то около 4 Гб или меньше. Обычно такой zip-файл распаковывается на моем ноутбуке за 20-60 секунд, но, конечно, на сервере с реальной системой хранения и более быстрым процессором распаковка будет меньше. Вы также не охарактеризовали параллелизм транзакций — сколько таких вещей будет происходить в любой момент времени. Я предполагаю, что параллелизм не особенно высок.

Если это так, я бы придерживался более простого подхода с асинхронным потоком. Вы делаете это в ASP.NET, я полагаю, на серверной ОС. CLR обеспечивает хорошее управление потоками, а ASP.NET — хорошие возможности масштабирования процессов. Таким образом, даже при высоких рабочих нагрузках вы получите хорошую загрузку ЦП и масштабирование без огромных усилий по настройке.

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

Но в вашем случае ничего из этого не похоже на распаковку zip-файлов.

person Cheeso    schedule 15.05.2009

Недостатки отдельной нити:

  1. Когда страница заканчивается, нет простого способа получить уведомление о том, что делает другой поток.
  2. Приложение можно было перезапустить в любой момент.
  3. Было бы легко случайно запустить процесс дважды, если пользователь отправляет страницу дважды подряд.
  4. Многопоточный код трудно отлаживать.

Преимущества отдельной нити:

  1. Меньше кода
  2. Легко запустить и забыть, если пользователю не нужно уведомлять о завершении распаковки.
  3. Никаких дополнительных работ по установке.

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

person Jonathan Parker    schedule 15.05.2009

Лично я бы пошел по маршруту службы Windows с обменом сообщениями между ними для прогресса, например, вернуть handle в распаковку, которую можно использовать для отслеживания состояния.

Однако я также думаю, что вы могли бы выделить поток, чтобы сделать это, и он будет успешно выполнен, и страница вернется.

person Lloyd    schedule 14.05.2009
comment
Каковы плюсы и минусы выполнения этого через отдельный поток или оконную службу? - person dev.e.loper; 14.05.2009

Я бы использовал асинхронный процесс, который вы можете легко опросить со страницы с поддержкой AJAX. По завершении часть страницы AJAX может представить детали, которые вы обычно представляли бы, пока пользователь ожидал синхронного завершения процесса.

person Wayne Hartman    schedule 14.05.2009