2

我有一个旧的 ASP.NET 应用程序。我们将 httpWebRequest 发送到远程 REST 服务器并取回 XML,大多数情况下应用程序运行良好。最近,我们每天都会遇到几次 CPU 使用率过高的问题。

在 CPU 使用率较高期间,我们监控了这些 httpWebRequest 连接(通过检查 w3wp 进程的 netstat)。一开始,连接从“ESTABLISHED”变为“CLOSE_WAIT”状态,然后这些连接超时后,这些连接一个接一个消失,然后再没有连接。

重置 IIS 后,当 w3wp.exe 进程再次启动时,我们仍然找不到与 httpWebRequest 目标服务器的任何连接。所以CPU使用率一直保持在高水平。即使经过几轮reset,也无法解决问题,直到我们看到一些连接开始连接到httpWebRequest目标服务器,CPU使用率下降了。

我实际上认为这可能是我的代码没有正确处理 httpWebRequest 的问题,我在这里发布了另一个问题:如何在捕获 httpwebrequest 超时后关闭底层连接?.

正如那个问题中提到的,我还发现了很多System.Net.HttpWebRequest.GetResponse(). 当 CPU 使用率真的很高时,我们在 5 分钟内发现了 3500 个相同的异常。

什么可以引起这种类型的问题,什么可能是药物?为什么应用程序不再发送请求(因为 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();
}
4

3 回答 3

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"));
}
于 2009-09-05T07:29:40.500 回答
2

根据您的描述,我不清楚您的高 CPU 使用率是否与您传出的 HTTP 请求有关。高 CPU 利用率可能是由于您的代码中的错误、CLR、IIS 中的错误或其他原因。在不知道哪个组件正在消耗 CPU 的情况下,您将无法做任何进一步的事情。

如果我是你,我会首先尝试将采样分析器附加到 W3WP 进程,然后查看哪个组件正在消耗 CPU。这应该指向您解决此问题的后续步骤。

于 2009-09-11T17:48:48.127 回答
2

查找 CPU 使用率高的原因可能需要一些时间,因为您必须找到导致问题的代码。我现在正在我最近开发的一个 vb.net 应用程序上解决这个问题。同时,我开发了一个页面,该页面有一个按钮,管理员可以单击该按钮来停止该W3WP.exe过程。在可以识别和更新问题代码之前,这是一个很好的权宜之计。这是我使用的代码。只需创建一个带有在相应页面上调用以下代码的按钮的 .aspx.aspx.vb页面。该代码使用命令提示符获取任务列表并将其写入文件。W3WP.exe然后,我为工作进程的 PID 解析文本文件。然后,我再次以编程方式访问命令提示符以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
于 2011-03-18T04:13:17.047 回答