У меня действительно любопытная проблема с HttpHandler, и я надеюсь, что кто-то здесь сможет пролить свет на это. Заранее большое спасибо за прочтение этого.
Мы создали HttpHandler, который находится в конвейере веб-сайта IIS, который обслуживает изображения, видео и другие ресурсы. HttpHandler очень легкий. Его единственная цель - проверить, существует ли запрошенный мультимедийный актив на диске, и, если это не так, переписать URL-адрес актива в место, где актив существует. Обработчик был создан таким образом, чтобы мы могли перенести наши медиаресурсы в новую структуру папок. Мы также планируем использовать обработчик (который в дальнейшем я буду называть URLRewriter) для SEO в URL-адресах изображений и видео.
Как уже упоминалось, класс URLRewriter очень легкий. Мы запустили профилирование памяти и определили, что во время работы он потребляет только около 12B памяти. Однако, когда мы помещаем обработчик в конвейер IIS, мы видим какое-то странное поведение, которое в конечном итоге приводит к большому потреблению памяти и, неизменно, к тому, что рабочий процесс w3 перезагружается. Поведение, которое мы видим, таково:
Когда поступает запрос на изображение в http://www.ourimageserver.com/media/a/b/c/d/image1xxl.jpg (не фактический URL), мы замечаем, что W3WP.exe создает и вешает дескриптор для каждой отдельной папки в пути к изображению:
• / сми
• / media / a
• / media / a / b
• / media / a / b / c
• / media / a / b / c / d
Это большая проблема, потому что у нас есть сотни тысяч медиаресурсов, которые хранятся в очень широкой и очень глубокой структуре папок. Количество дескрипторов, созданных IIS / W3WP, быстро растет, когда URLRewriter развернут в нашей производственной среде, и потребление памяти W3WP соответственно возрастает. Менее чем за час работы (при относительно тихом периоде с точки зрения трафика) количество дескрипторов, удерживаемых W3WP, превысило 22000, и процесс прекратился. Мы также заметили, что использование памяти ядра увеличилось на серверах, где был развернут URLRewriter.
Тщательный анализ поведения W3WP с использованием Process Explorer и Process Monitor (как с отладчиком VS, так и без него) показал, что дескрипторы создаются до вызова URLRewriter. Фактически, дескрипторы создаются за до события BeginRequest. Когда URLRewriter удаляется из конвейера, ни один из этих дескрипторов не создается. Теперь действительно любопытно, что создается впечатление, что дескрипторы создаются в результате операции NotifyChangeDirectory, выполняемой W3WP. Зачем W3WP запрашивать уведомление об изменениях в этих каталогах? И как мы можем предотвратить это? Конечно, это не поведение по умолчанию / нормальное поведение?
Если у вас есть идеи относительно того, что может быть причиной этой проблемы, я был бы очень признателен за ваш вклад. Поведение одинаково на IIS6 и IIS7.