Я не ищу альтернативу содержимого потокового файла из базы данных, действительно, я ищу корень проблемы, это было запуск файла до IIS 6, где мы запускали наше приложение в классическом режиме, теперь мы обновил наш IIS до 7, и мы запускаем пул приложений в режиме конвейера и эта проблема началась.
У меня есть обработчик, где я должен доставлять большие файлы в запрос клиента. И я сталкиваюсь с следующими проблемами:
Файлы имеют средний размер от 4 до 100 МБ, поэтому рассмотрим 80-мегабайтный файл для загрузки файлов.
Буферизация включена, Медленный старт
Response.BufferOutput = True;
Это приводит к очень медленному запуску файла, так как загрузка пользователя и даже индикатор выполнения не отображаются до нескольких секунд, обычно от 3 до 20 секунд, причина в том, что IIS сначала считывает весь файл, определяет длину содержимого, а затем начинает передача файла. Файл воспроизводится в видеоплеере, и он работает очень медленно, однако iPad сначала загружает часть файла, чтобы он работал быстро.
Буферизация выключена, нет длины контента, быстрого запуска, отсутствия прогресса
Reponse.BufferOutput = False;
Это приводит к немедленному запуску, однако конечный клиент (типичный браузер, такой как Chrome) не знает Content-Length, поскольку IIS тоже не знает, поэтому он не отображает прогресс, вместо этого он говорит, что загружен X KB.
Буферизация, Ручная длина содержимого, Быстрый старт, Прогресс и нарушение протокола
Response.BufferOutput = False;
Response.AddHeader("Content-Length", file.Length);
Это приводит к правильной немедленной загрузке файлов в Chrome и т.д., однако в некоторых случаях обработчик IIS приводит к ошибке "Удаленное закрытие клиента" (это очень часто), а другие результаты WebClient приводят к нарушению протокола. Это происходит от 5 до 10% всех запросов, а не от всех запросов.
Я предполагаю, что происходит, IIS не посылает ничего, называемое 100 continue, когда мы не делаем буферизации, и клиент может отключиться, не ожидая выхода. Однако чтение файлов из источника может занять больше времени, но на стороне клиента я увеличил тайм-аут, но, похоже, отключен от IIS и не контролирует.
В любом случае я могу заставить Response отправить 100 continue и не позволить кому-либо закрыть соединение?
UPDATE
Я нашел следующие заголовки в Firefox/Chrome, здесь нет ничего необычного для нарушения протокола или плохого заголовка.
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:POST, GET, OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:1728000
Cache-Control:private
Content-Disposition:attachment; filename="24.jpg"
Content-Length:22355
Content-Type:image/pjpeg
Date:Wed, 07 Mar 2012 13:40:26 GMT
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
ОБНОВЛЕНИЕ 2
Turning Recycling все еще не предлагал многого, но я увеличил MaxWorkerProcess до 8, и теперь я получаю меньше ошибок, чем раньше.
Но в среднем из 200 запросов за одну секунду от 2 до 10 запросов терпят неудачу.., и это происходит почти каждые секунды.
ОБНОВЛЕНИЕ 3
Продолжение 5% запросов с ошибкой "Сервер зафиксировал нарушение протокола. Раздел = ResponseStatusLine", у меня есть другая программа, которая загружает контент с веб-сервера, который использует WebClient, и который дает эту ошибку 4-5 раз в секунду, в среднем у меня 5% запросов не удается. Есть ли способ отслеживать сбой WebClient?
Проблемы с переопределением
Полученный файл с нулевым байтом
IIS закрывает соединение по какой-либо причине, на стороне клиента в WebConfig, я получаю 0 байтов для файла, который не равен нулю, мы делаем проверку SHA1 хешей, это говорит нам, что на веб-сервере IIS ошибка не записывается.
Это была моя ошибка, и она была решена, поскольку мы используем Entity Framework, она читала грязные (незафиксированные строки), поскольку чтение не было в области транзакций, поэтому в область транзакции была разрешена эта проблема.
Исключено нарушение правил протокола
WebClient выдает сообщение WebException: "Сервер совершил нарушение протокола. Раздел = ResponseStatusLine.
Я знаю, что могу включить небезопасный синтаксический анализ заголовков, но это не так, когда это мой обработчик HTTP, который отправляет соответствующие заголовки, не знаю, почему IIS отправляет что-нибудь лишнее (проверено на firefox и chrome, ничего необычного), это происходит только 2% раз.
ОБНОВЛЕНИЕ 4
Обнаружена ошибка sc-win32 64, и я где-то читал, что WebLimits для MinBytesPerSecond должен быть изменен с 240 на 0, но все одинаково. Однако я заметил, что всякий раз, когда IIS регистрирует 64 ошибки sc-win32, IIS регистрирует статус HTTP как 200, но была некоторая ошибка. Теперь я не могу включить Failed Trace Logging для 200, потому что это приведет к массивным файлам.
Обе указанные проблемы были решены путем увеличения MinBytesPerSecond, а также отключения сеансов, я добавил подробный ответ, суммирующий каждую точку.