Производительность ASP.NET Request.Form
Я использовал HttpHandler
для создания легкого веб-сервиса, предназначенного для высокой производительности. Для этого требуется POST
с типом контента application/x-www-form-urlencoded
. Веб-служба выполняет множество задач, включая дешифрование, работу с базами данных, бизнес-логику и т.д. Во время тестирования нагрузки монитор производительности (ANTS и Visual Studio) указывает на одну строку кода, которая занимает большую часть времени, на самом деле 67%.
string value = context.Request.Form[MY_FORM_KEY];
В нижней части стека вызовов для этой строки кода монитор производительности говорит об этом вызове:
System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest();
является виновником.
Может кто-нибудь помочь, пожалуйста, объясните?! Приложение находится в .Net 4, опубликованном как релиз, IIS 7, на Windows Server 2008.
Спасибо,
Джо Джей Барретт
Ответы
Ответ 1
Задержка времени происходит, потому что IIS пытается считывать поток запросов от клиента для получения значений формы. Этот поток зависит от клиентского подключения и по некоторым причинам даже не возвращается. Я видел случаи, когда Request.Form блокируется более 5 минут, и это приведет к тому, что IIS в конечном итоге бросит ThreadAbortException.
В нашем случае у нас был HttpModule, который должен был прочитать значения Request.Form(или запросить [ "ключ" ], который также выполняет итерацию над значениями формы), и он будет произвольно блокироваться на сервере и никогда не вернется. Я использовал этот HttpModule для отслеживания производительности приложений на стороне сервера, что заставило меня понять, что все, что я отслеживаю с помощью этого модуля, также будет зависеть от клиентских подключений, что исказит результаты выполнения на стороне сервера.
Чтобы устранить эту проблему, вы можете установить обратный HTTP-прокси перед своим приложением. Обратный прокси отключит ответственность за чтение клиентского потока (и блокирует дорогой поток в вашем приложении) и отправит полный запрос на ваш сервер. Это уменьшит нагрузку на ваше приложение, поскольку вы можете сохранить свои драгоценные потоки приложений для работы с основной рабочей нагрузкой, а не для их блокировки для чтения из клиентских потоков.
Кроме того, вы можете отключать HTTP, балансировку нагрузки и даже кэшировать некоторый статический контент на вашем обратном прокси (в зависимости от того, какой из них вы используете).
Ответ 2
System.Web.Hosting.UnsafeIISMethods.MgdSyncReadRequest()
- импортированная функция IIS (как вы, возможно, догадались). Поскольку http.sys, бит, который выполняет всю работу http для IIS, является неуправляемым кодом, в какой-то момент ваше приложение должно будет поговорить с ним, хотя и не напрямую.
То, что я думаю, происходит, когда вы читаете коллекцию форм,.net читает это из необработанного запроса от IIS. Если это окажется бутылочной горловиной, я бы реорганизовал ваш код, чтобы читать данные формы асинхронно и хранить нужные значения в собственной структуре данных.
Саймон
Ответ 3
MgdSyncReadRequest
метод заблокировал внутренний неуправляемый-IIS API. Но поднял управляемый ThreadAbortException
.
Это означает, что другой управляемый поток может быть вызван Thread.Abort()
.
Я искал sourcesource, получил его "RequestTimeoutManager
":
http://referencesource.microsoft.com/#System.Web/RequestTimeoutManager.cs,177
thread.Abort(new HttpApplication.CancelModuleException(true));
Решение (не проверять, может быть): Реализовано с помощью асинхронного чтения и вручную обрабатывает тайм-аут...