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

StackOverflow https://stackoverflow.com/questions/863707

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие советы

Недостатками отдельного потока являются:

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top