2009-09-04 3 views
1

У меня есть старое приложение ASP.NET. Мы отправляем httpWebRequest на удаленный сервер REST и извлекаем XML обратно, большую часть времени приложение работает нормально. В последнее время мы получили несколько проблем с загрузкой процессора несколько раз в день.ASP.NET HttpWebRequest прекратить отправку запросов, высокий уровень использования процессора

Во время высокой загрузки процессора мы отслеживали эти подключения httpWebRequest (путем проверки netstat для процесса w3wp). В самом начале соединения меняются на статус «CLOSE_WAIT» с «ESTABLISHED», а после этого таймаута соединения эти соединения исчезают один за другим, а затем нет никакого соединения.

После перезагрузки IIS, когда процесс w3wp.exe запустился снова, мы все равно не смогли найти никаких соединений с целевым сервером httpWebRequest. Таким образом, использование ЦП продолжает оставаться на высоком уровне. Даже после нескольких раундов перезагрузки он не решит проблему, пока мы не увидим, что некоторые соединения начинают подключаться к целевому серверу httpWebRequest, использование процессора снизилось.

Я действительно думал, что это может быть проблема с моим кодом, который не обрабатывает httpWebRequest должным образом, я разместил здесь еще один вопрос: How to close underlying connections after catch httpwebrequest timeout?.

Как упоминалось в этом вопросе, я также нашел много исключений таймаута для System.Net.HttpWebRequest.GetResponse(). Мы обнаружили 3500 таких же исключений за 5 минут, когда использование ЦП действительно велико.

Что может сделать этот тип проблемы и что может быть лекарством? Почему приложение не отправляет запрос больше (поскольку в netstat нет соединения)?

Вот исходный код только в случае, если:

System.Net.HttpWebResponse httpWebResponse = null; 
System.IO.Stream stream = null; 
XmlTextReader xmlTextReader = null; 
try 
{ 
    System.Net.HttpWebRequest httpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(request); 
    httpWebRequest.ReadWriteTimeout = 10000; 
    httpWebRequest.Timeout = 10000; 
    httpWebRequest.KeepAlive = false; 
    httpWebRequest.Method = "GET"; 
    httpWebResponse = (System.Net.HttpWebResponse)httpWebRequest.GetResponse(); 
    stream = httpWebResponse.GetResponseStream(); 
    xmlTextReader = new XmlTextReader(stream); 
    xmlTextReader.Read(); 
    xmlDocument.Load(xmlTextReader); 
    //Document processing code. 
    //... 
} 
catch 
{ 
    //Catch blcok with error handle 
} 
finally 
{ 
    if (xmlTextReader != null) 
     xmlTextReader.Close(); 
    if (httpWebResponse != null) 
     httpWebResponse.Close(); 
    if (stream != null) 
     stream.Close(); 
} 

ответ

2

Из вашего описания, это не ясно, что ваше высокое использование ЦП связано с вашими исходящими HTTP-запросами. Высокое использование ЦП может быть связано с ошибкой в ​​вашем коде, ошибкой в ​​CLR, IIS или чем-то еще. Не зная, какой компонент потребляет процессор, вы не сможете ничего сделать.

Если бы я был вами, я бы сначала попытался подключить профилировщик выборки к процессу W3WP и посмотреть, какой компонент потребляет процессор. Это должно указывать на следующие шаги в решении этой проблемы.

+0

@feroze, спасибо большое за помощь, у меня нет опыта в профилировщике пробоотбора, не могли бы вы дать мне более подробную информацию или некоторые ссылки, которые я могу изучить. Еще раз спасибо. – machinegone

+0

Вы можете скачать профайлер CLR здесь: http://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&displaylang=en Вот несколько ссылок, которые показывают, как использовать профайлер: http://msdn.microsoft.com/en-us/library/ms979205.aspx http://msdn.microsoft.com/en-us/magazine/cc300553.aspx Я просто искал на ваш код снова, и что-то привлекло мое внимание. Поскольку вы добавляете XMLTextReader() в поток, также возможно, что анализ XML-документа может потреблять ЦП, если документ очень сложный. – feroze

+0

@feroze, еще раз спасибо, я буду читать руководство и запускать его на своем сервере. Я дам вам обновление позже. Благодарю. – machinegone

2

Я хотел бы предложить вам попробовать посылать запросы асинхронно, чтобы избежать блокировки основного потока:

using (var client = new WebClient()) 
{ 
    client.OpenReadCompleted += (sender, e) => 
    { 
     using (var reader = XmlReader.Create(e.Result)) 
     { 
      // Process the XML document here 
     } 
    }; 
    client.OpenReadAsync(new Uri("http://www.example.com")); 
} 
+0

Дарин, спасибо, я попробую этот способ, чтобы узнать, может ли он помочь мне решить проблему. – machinegone

2

Поиск причины высокой загрузки процессора может занять некоторое время, так как вам придется найти код, вызывающий проблему. Я работаю над этим прямо сейчас в приложении vb.net, которое я недавно разработал. Тем временем я разработал страницу с кнопкой, которую администратор может нажать, чтобы остановить процесс W3WP.exe. Это отличная мера остановки, пока код проблемы не может быть идентифицирован и обновлен. Вот код, который я использовал. Просто создайте страницу .aspx с кнопкой, которая вызывает следующий код на соответствующей странице .aspx.vb. Код использует командную строку для получения списка задач и записи в файл. Затем я разбираю текстовый файл для PID рабочего процесса W3WP.exe. Затем я снова обращаюсь к командной строке, чтобы завершить процесс W3WP.exe с использованием PID.

Imports System.Web 

Partial Class TAP 
Inherits System.Web.UI.Page 

Protected Sub btnStop_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStop.Click 
    Call thStop_IIS() 
End Sub 

Function thStop_IIS() 

    Dim varRetval As String 
    Dim varPID As String 
dim x as long 
    Dim savePath As String = Request.PhysicalApplicationPath + "exports\" 
    If Dir(savePath + "filename.txt") = "filename.txt" Then 
     Kill(savePath + "filename.txt") 
    End If 

    varRetval = Shell("cmd /c tasklist > " + savePath + "filename.txt") 

    For x = 1 To 90000000 

    Next x 

    varPID = thParse_File_Return_PID(savePath + "filename.txt") 
    varRetval = Shell("cmd /c taskkill /pid " & varPID & " /F") 
    Return True 
End Function 

Function thParse_File_Return_PID(ByVal varFileToParse As String) As Integer 

    On Error GoTo handler_err 

    'Dim FILE_NAME As String = "C:\Users\Owner\Documents\test.txt" 
    Dim FILE_NAME As String = varFileToParse 
    Dim TextLine As String 
    Dim varPID As Integer 
    Dim x As Long 

    If System.IO.File.Exists(FILE_NAME) = True Then 

     Dim objReader As New System.IO.StreamReader(FILE_NAME) 

     Do While objReader.Peek() <> -1 
      'TextLine = TextLine & objReader.ReadLine() & vbNewLine 
      TextLine = objReader.ReadLine() & vbNewLine 
      If InStr(TextLine, "w3wp.exe") Then 
       varPID = Mid(TextLine, 31, 4) 
      End If 
     Loop 

     thParse_File_Return_PID = varPID 

    Else 
     thParse_File_Return_PID = 0 
    End If 



handler_exit: 
    Exit Function 

handler_err: 
    'MsgBox(Err.Number & " " & Err.Description & ":" & "thParse_File_Return_Pages") 
    Resume 

End Function 

End Class 
Смежные вопросы