WCF超时异常详细调查

Jas*_*ley 94 wcf timeout timeoutexception

我们有一个应用程序,它具有在IIS7上运行的WCF服务(*.svc)以及查询该服务的各种客户端.服务器正在运行Win 2008 Server.客户端正在运行Windows 2008 Server或Windows 2003服务器.我得到以下异常,我看到它实际上可能与大量潜在的WCF问题有关.

System.TimeoutException: The request channel timed out while waiting for a reply after 00:00:59.9320000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The HTTP request to 'http://www.domain.com/WebServices/myservice.svc/gzip' has exceeded the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. 
Run Code Online (Sandbox Code Playgroud)

我已将超时时间增加到30分钟,但错误仍然存​​在.这告诉我其他东西正在发挥作用,因为数据量永远不会需要30分钟才能上传或下载.

错误来来去去.目前,它更频繁.如果我有3个客户端同时运行或100个,似乎并不重要,它仍然会偶尔发生.大多数时候,没有超时,但我仍然每小时得到一些.该错误来自任何调用的方法.其中一种方法没有参数并返回一些数据.另一个接收大量数据作为参数但异步执行.错误始终源自客户端,并且永远不会引用堆栈跟踪中服务器上的任何代码.它始终以:

 at System.Net.HttpWebRequest.GetResponse()
  at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
Run Code Online (Sandbox Code Playgroud)

在服务器上:我已经尝试过(现在有)以下绑定设置:

maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647"
Run Code Online (Sandbox Code Playgroud)

它似乎没有影响.

我已经尝试过(现在有)以下限制设置:

<serviceThrottling maxConcurrentCalls="1500"   maxConcurrentInstances="1500"    maxConcurrentSessions="1500"/>
Run Code Online (Sandbox Code Playgroud)

它似乎没有影响.

我目前有WCF服务的以下设置.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
Run Code Online (Sandbox Code Playgroud)

我跑ConcurrencyMode.Multiple了一会儿,但错误仍然发生.

我尝试重新启动IIS,重新启动我的底层SQL Server,重新启动计算机.所有这些似乎都没有影响.

我试过禁用Windows防火墙.它似乎没有影响.

在客户端上,我有以下设置:

maxReceivedMessageSize="2147483647"

<system.net>
    <connectionManagement>
    <add address="*" maxconnection="16"/>
</connectionManagement> 
</system.net>
Run Code Online (Sandbox Code Playgroud)

我的客户关闭了它的连接:

var client = new MyClient();

try
{
    return client.GetConfigurationOptions();
}
finally
{
    client.Close();
}
Run Code Online (Sandbox Code Playgroud)

我已更改注册表设置以允许更多传出连接:

MaxConnectionsPerServer=24, MaxConnectionsPer1_0Server=32.
Run Code Online (Sandbox Code Playgroud)

我现在刚刚尝试过SvcTraceViewer.exe.我设法在客户端捕获一个例外.我看到它的持续时间是1分钟.查看服务器端跟踪,我可以看到服务器不知道此异常.我能看到的最长持续时间是10秒.

我查看了在exec sp_who服务器上使用的活动数据库连接.我只有几个(2-3).我已经使用TCPview查看了来自一个客户端的TCP连接.它通常是2-3左右,我见过5或6.

简单地说,我很难过.我已经尝试了所有我能找到的东西,并且必须遗漏一些WCF专家能够看到的非常简单的东西.我的直觉是,在服务器实际收到消息和/或某些东西在服务器级别对消息进行排队并且从不让它们处理之前,某些东西阻止了我的客户端在低级别(TCP).

如果您有任何性能指标我应该看一下,请告诉我.(请说明哪些值不好,因为其中一些计数器很难去除).另外,我如何记录WCF消息大小?最后,我们那里有什么工具可以让我测试我可以在客户端和服务器之间建立多少连接(独立于我的应用程序)

谢谢你的时间!

6月20日增加的额外信息:

我的WCF应用程序执行类似于以下操作.

while (true)
{
   Step1GetConfigurationSettingsFromServerViaWCF(); // can change between calls
   Step2GetWorkUnitFromServerViaWCF();
   DoWorkLocally(); // takes 5-15minutes. 
   Step3SendBackResultsToServerViaWCF();
}
Run Code Online (Sandbox Code Playgroud)

使用WireShark,我确实看到错误发生时,我有五次TCP重新传输,然后是TCP重置.我的猜测是RST来自WCF终止连接.我得到的异常报告来自Step3超时.

我通过查看tcp流"tcp.stream eq 192"发现了这一点.然后我将我的过滤器扩展为"tcp.stream eq 192和http和http.request.method eq POST",并在此流中看到了6个POST.这看起来很奇怪,所以我检查了另一个流,如tcp.stream eq 100.我有三个POST,这似乎更正常,因为我正在做三个电话.但是,我会在每次WCF调用后关闭我的连接,所以我希望每个流一个调用(但我不太了解TCP).

再调查一下,我把http数据包加载到磁盘上,看看这六个调用在哪里.

1) Step3
2) Step1
3) Step2
4) Step3 - corrupted
5) Step1
6) Step2
Run Code Online (Sandbox Code Playgroud)

我的猜测是两个并发客户端正在使用相同的连接,这就是我看到重复的原因.但是,我还有一些我无法理解的问题:

a)为什么数据包已损坏?随机网络侥幸 - 也许?使用以下示例代码对负载进行gzip压缩:http://msdn.microsoft.com/en-us/library/ms751458.aspx - 如果同时使用代码,代码可能会偶尔发生错误吗?我应该在没有gzip库的情况下进行测试.

b)为什么在损坏的操作超时后我会看到第1步和第2步运行?在我看来好像这些操作不应该发生.也许我没有看到正确的流,因为我对TCP的理解是有缺陷的.我有其他流同时发生.我应该调查其他流 - 快速浏览一下流190-194,显示Step3 POST具有适当的有效载荷数据(未损坏).推动我再次查看gzip库.

Mub*_*har 50

如果您使用.Net客户端,那么您可能没有设置

//This says how many outgoing connection you can make to a single endpoint. Default Value is 2
System.Net.ServicePointManager.DefaultConnectionLimit = 200;
Run Code Online (Sandbox Code Playgroud)

这是原始问题和答案WCF服务限制

更新:

此配置进入.Net客户端应用程序可能在启动时或在开始测试之前.

此外,你可以在app.config文件中使用它,如下所示

<system.net>
    <connectionManagement>
      <add maxconnection = "200" address ="*" />
    </connectionManagement>
  </system.net>
Run Code Online (Sandbox Code Playgroud)

  • 它只花了一年时间,但我终于在应用程序上运行了另一个压力测试,并设置了此标志.问题似乎已经解决,所以我给你最好的答案.我不会感到惊讶的是,这是所需的最后一块拼图,但是所有其他元素都需要到位以确保错误不会发生.非常感谢! (3认同)
  • @Aris:在.net客户端应用程序中,在启动时或者你设置全局配置的地方,如果你想保持它的可配置性,你可以将它添加到配置文件中,就像这样<system.net> <connectionManagement> <add maxconnection = "200"address ="*"/> </ connectionManagement> </system.net> (2认同)