Как диагностировать «время ожидания операции» HttpException

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

Вопрос

Я вызываю 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.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top