2010-03-10 62 views
3

我调用5个外部服务器为我的IIS 6服务器上的特定网页的每个请求检索基于XML的数据。目前的数据量在每秒3-5个传入请求之间,这意味着每秒传出15-20个请求。如何诊断“操作超时”HttpException

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 

有什么建议吗?

回答

0

你说你正在为ASP页面的每个传入请求做5个传出请求。那5台不同的服务器,还是同一台服务器?

在发布下一个请求之前,您是否等待先前的请求完成?超时是在等待连接时发生,还是在请求/响应过程中发生?

如果在请求/响应期间发生超时,那么这意味着目标服务器处于压力之下。唯一的方法就是在其中一台机器上运行wireshark/netmon,然后查看网络跟踪以查看来自应用的请求是否能够传递给服务器,以及是否是否目标服务器在给定的超时内响应。

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

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

对不起,这里没有简单的答案。这是你需要探索的很多途径。如果我是你,当你开始获取超时并执行前面描述的操作时,我会先将windbg.exe附加到w3wp。

+0

传出的请求(以及针对该事件的传入)都在一个具有一个IP地址(以太网10meg)的服务器上。现在只尝试尝试同步,因为我想在转换为异步之前确保代码正常工作。 asp.net - >请求排队计数器很少非零,所以不会导致任何地方。请求量确实限制了调试器或wireshark工具的使用。在平均每天超过1M次的请求中发现100个每日超时之一是艰难的。非常感谢您的评论。 – dalej 2010-03-31 15:56:57

+0

这并不难 - 只要将windbg.exe附加到W3WP进程,当您开始获取超时异常,转储进程(.dump/ma <文件名)并分离调试器。然后您可以重新启动调试器,加载之前创建的转储,然后调试... – feroze 2010-04-01 23:09:06

2

默认情况下,HttpWebRequest将每个HTTP/1.1服务器限制为2个连接。因此,如果您的请求需要一定的时间才能完成,并且您的服务器上有传入的请求排队,那么您将无法使用连接,从而导致超时。

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

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

早就已经把machine.config中的* MAX CONNECTIONS *改成了200,并且设置了* ServicePointManager.DefaultConnectionLimit = 200 *来测试。另外,在超时异常时,我测试了ServicePointManager.DefaultConnectionLimit以确保它具有较高的值。我还设置的最大端口数: [HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \服务\ TCPIP \参数] MaxUserPort的= 5000(默认为5000,最大值= 65534) 参见:[这] [1] [1]:http://smallvoid.com/article/winnt-tcpip-max-limit.html – dalej 2010-03-16 13:49:08

+0

如果是资源稀缺问题,它必须是连接,端口或线程之一。还有别的吗?我应该有足够的连接和端口给予我的设置和Perfmon显示我在任何时候都有12K的线程,但* TCPIP /连接失败*每5-10秒增加一次。当然,它可能只是另一端,但如何诊断这一点。更好的是,当许多超时正在发生时,人们如何保持性能?我真的很困惑。 – dalej 2010-03-16 13:49:31

+0

你能给出确切的异常堆栈跟踪吗? – feroze 2010-03-19 22:12:34