Как диагностировать «время ожидания операции» HttpException
-
19-09-2019 - |
Вопрос
Я вызываю 5 внешних серверов для получения данных на основе XML для каждого запроса определенной веб-страницы на моем сервере IIS 6.Текущий объем составляет 3–5 входящих запросов в секунду, что означает 15–20 исходящих запросов в секунду.
99% исходящих запросов с моего сервера (клиента) на внешние серверы (сервер) работают нормально, но около 100-200 в день заканчиваются исключением «Время ожидания операции истекло».
Это говорит о том, что у меня проблема с ресурсами на моем сервере - некоторая нехватка сокетов, портов и т. д. или блокировка потока, но проблема этой теории в том, что сбои полностью случайны - нет нескольких запросов подряд, которые все завершаются неудачно - и на два внешних сервера приходится большая часть сбоев.
Мой вопрос: как я могу дополнительно диагностировать эти исключения, чтобы определить, возникла ли проблема на моей стороне (клиенте) или на другой стороне (серверах)?
Объем запросов не позволяет поставить анализатор на провод — уловить эти немногие исключения будет очень сложно.Я сбросил СОЕДИНЕНИЯ и ПОТОКИ в моем файле Machine.config, и основной код выглядит так:
Dim hRequest As HttpWebRequest
Dim responseTime As String
Dim objWatch As New Stopwatch
Try
' calculate time it takes to process transaction
objWatch.Start()
hRequest = System.Net.WebRequest.Create(url)
' set some defaults
hRequest.Timeout = 5000
hRequest.ReadWriteTimeout = 10000
hRequest.KeepAlive = False ' to prevent open HTTP connection leak
hRequest.SendChunked = False
hRequest.AllowAutoRedirect = True
hRequest.MaximumAutomaticRedirections = 3
hRequest.Accept = "text/xml"
hRequest.Proxy = Nothing 'do not waste time searching for a proxy
hRequest.ServicePoint.Expect100Continue = False
Dim feed As New XDocument()
' use *Using* to auto close connections
Using hResponse As HttpWebResponse = DirectCast(hRequest.GetResponse(), HttpWebResponse)
Using reader As XmlReader = XmlReader.Create(hResponse.GetResponseStream())
feed = XDocument.Load(reader)
reader.Close()
End Using
hResponse.Close()
End Using
objWatch.Stop()
' Work here with returned contents in "feed" document
Return XXX' some results here
Catch ex As Exception
objWatch.Stop()
hRequest.Abort()
Return Nothing
End Try
Какие-либо предложения?
Решение
Вы сказали, что делаете 5 исходящих запросов на каждый входящий запрос на страницу ASP.Это 5 разных серверов или один и тот же?
Ждете ли вы завершения предыдущего запроса, прежде чем отправлять следующий?Тайм-аут происходит во время ожидания соединения или во время запроса/ответа?
Если тайм-аут происходит во время запроса/ответа, это означает, что целевой сервер находится в состоянии стресса.Единственный способ выяснить, так ли это, — запустить Wireshark/netmon на одном из компьютеров и просмотреть трассировку сети, чтобы узнать, доходит ли вообще запрос от приложения до сервера, и если он заключается в том, отвечает ли целевой сервер в течение заданного времени ожидания.
Если это проблема нехватки потоков, то один из способов ее диагностики — подключить отладчик Windbg.exe к процессу w3wp.exe, когда у вас начинается тайм-аут.Затем загрузите расширение отладки sos.dll.И запустите команду !threads, а затем команду !threadpool.Он покажет вам, сколько рабочих потоков и потоков портов завершения используются/остаются.Если количество потоков #completionport или рабочих потоков низкое, это будет способствовать тайм-ауту.
Альтернативно вы можете отслеживать счетчики производительности ASP.NET и System.net.Посмотрите, монотонно ли увеличивается очередь запросов ASP.NET — это может указывать на то, что ваши исходящие запросы выполняются недостаточно быстро.
Извините, здесь нет простых ответов.Вам придется исследовать множество направлений.На вашем месте я бы начал с подключения Windbg.exe к w3wp, когда у вас начнутся таймауты, и сделал бы то, что я описал ранее.
Другие советы
По умолчанию HttpWebRequest ограничивает вас двумя подключениями на сервер HTTP/1.1.Таким образом, если для выполнения ваших запросов требуется время, и у вас есть входящие запросы в очереди на сервере, у вас закончится соединение и, следовательно, возникнут таймауты.
Вам следует изменить максимальное количество исходящих подключений в ServicePointManager.
ServicePointManager.DefaultConnectionLimit = 20 // or some big value.