【问题标题】:How to diagnose "the operation has timed out" HttpException如何诊断“操作已超时”HttpException
【发布时间】:2010-03-10 17:25:52
【问题描述】:

我正在调用 5 个外部服务器来为我的 IIS 6 服务器上的特定网页的每个请求检索基于 XML 的数据。目前的数量在每秒 3-5 个传入请求之间,这意味着每秒 15-20 个传出请求。

从我的服务器(客户端)到外部服务器(服务器)的传出请求中有 99% 工作正常,但每天约有 100-200 个以“操作已超时”异常结束。

这表明我的服务器上存在资源问题 - 套接字、端口等短缺或线程锁,但这个理论的问题是故障完全是随机的 - 没有连续的请求数量全部失败 - 其中两个外部服务器导致了大部分失败。

我的问题是如何进一步诊断这些异常以确定问题是在我端(客户端)还是在另一端(服务器)?

请求的数量使分析器无法在线上进行 - 捕获这几个异常将非常困难。我在 machine.config 中重置了 CONNECTIONS 和 THREADS,基本代码如下所示:

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

有什么建议吗?

【问题讨论】:

    标签: vb.net httpwebrequest asp.net-3.5 httpexception


    【解决方案1】:

    默认情况下,HttpWebRequest 将每个 HTTP/1.1 服务器限制为 2 个连接。因此,如果您的请求需要一些时间才能完成,并且您有传入的请求在服务器上排队,您将失去连接并因此超时。

    您应该更改 ServicePointManager 上的最大传出连接数。

    ServicePointManager.DefaultConnectionLimit = 20 // or some big value.
    

    【讨论】:

    • 很久以前,我将 machine.config 中的 MAX CONNECTIONS 都更改为 200 并设置 ServicePointManager.DefaultConnectionLimit = 200 只是为了测试。此外,在超时异常上,我测试了 ServicePointManager.DefaultConnectionLimit 以确保它具有较高的值。我还设置了最大端口数: [HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters] MaxUserPort = 5000(默认 = 5000,Max = 65534)请参阅:[this][1] [1]:smallvoid.com/article/winnt-tcpip-max-limit.html
    • 如果是资源稀缺问题,必须是连接、端口或线程之一。还能有别的吗?考虑到我的设置,我应该有足够的连接和端口,Perfmon 显示我在任何时候都有 12K 的线程,但 TCPIP/Connection Failures 每 5-10 秒增加一个。当然,它可能只是另一端,但如何诊断。更好的是,当发生许多超时时,如何保持性能?我真的对此感到迷惑。
    • 你能给出确切的异常堆栈跟踪吗?
    • 错误很简单:异常是:操作超时响应时间:3001毫秒,Url是:等等,等等3001的超时是由于将超时重置为3秒。
    【解决方案2】:

    您说您对 ASP 页面的每个传入请求执行 5 个传出请求。那是5个不同的服务器,还是同一个服务器?

    在发出下一个请求之前,您是否等待上一个请求完成?超时是在等待连接时发生还是在请求/响应期间发生?

    如果在请求/响应期间发生超时,则意味着目标服务器处于压力之下。找出是否是这种情况的唯一方法是在其中一台机器上运行 wireshark/netmon,并查看网络跟踪以查看来自应用程序的请求是否甚至通过服务器,如果它即,目标服务器是否在给定的超时时间内响应。

    如果这是一个线程不足问题,那么诊断它的方法之一是在您开始超时时将 windbg.exe 调试器附加到 w3wp.exe 进程。然后加载 sos.dll 调试扩展。并运行 !threads 命令,然后运行 ​​!threadpool 命令。它将向您显示使用/剩余多少工作线程和完成端口线程。如果#completionport 线程或工作线程较低,则会导致超时。

    或者,您可以监视 ASP.NET 和 System.net 性能计数器。查看 ASP.NET 请求队列是否单调增加 - 这可能表明您的传出请求完成速度不够快。

    抱歉,这里没有简单的答案。您需要探索许多途径。如果我是你,我会在你开始超时时将 windbg.exe 附加到 w3wp 并执行我之前描述的操作。

    【讨论】:

    • 传出的请求(以及传入的请求)都在一台具有一个 IP 地址(以太网 10meg)的服务器上。现在尝试同步进行只是因为我想确保代码在转换为异步之前正常工作。 asp.net -> requests 排队计数器很少是非零的,因此不会导致任何地方。请求的数量确实限制了调试器或 wireshark 工具的使用。在平均每天超过 100 万个请求中找到每天 100 次超时之一是很困难的。非常感谢您的 cmets。
    • 这并不难 - 只需在您开始收到超时异常时将 windbg.exe 附加到 W3WP 进程,转储进程 (.dump /ma
    猜你喜欢
    • 2021-10-22
    • 2010-10-01
    • 1970-01-01
    • 2012-09-21
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多