无法解释的 WCF 服务超时
运行调用 WCF 服务的 MVC 网站。
站点和服务位于两台不同的机器上。
.NET框架4; IIS 7。
生产站点在不应该发生的情况下遇到了超时。我创建了最简单的示例(调用延迟后返回“嗨妈妈”的服务方法的简单网站)并且能够重现该问题。具体情况如下:
- 客户端 Web 应用程序将其绑定的 SendTimeout 设置为 6 分钟。
- 服务器服务什么也不做,只是将一条消息写入文件,休眠 5 分钟,然后写入另一条消息。
- 写入服务器文件的消息是正确的;服务器跟踪显示没有问题。
- 客户端永远不会从服务器服务方法接收返回值。就像它刚刚失去了与服务器的连接一样。
- 客户端在 6 分钟后抛出 TimeoutException(任何大于该值的超时只会进一步延迟异常)。 如果我将服务器上的线程睡眠时间更改为 4 分钟,则一切正常。这是可重复的,并且没有其他人搞乱这个测试场景。
因此,这是客户端的相关配置部分:
<binding name="BasicHttpBinding_IService1"
closeTimeout="00:6:00"
openTimeout="00:6:00"
receiveTimeout="00:6:00"
sendTimeout="00:6:00"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
messageEncoding="Text"
textEncoding="utf-8"
transferMode="Buffered"
useDefaultWebProxy="true">
<httpRuntime executionTimeout="1200"
maxRequestLength="10240" />
<serviceBehaviors>
<behavior>
<serviceTimeouts transactionTimeout="00:6:00" />
</behavior>
</serviceBehaviors>
服务器上存在相同的值。 以下包括我尝试过的内容:
- 在上面添加了 serviceTimeouts 元素。
- 确保在客户端代理类上调用 close (尽管这在我的情况下不是问题,因为每次都会发生错误)。
- 显式创建通道,转换为 IContextChannel 并设置 OperationTimeout(如此处所述)。
- 增加了 IIS 中服务器应用程序池的 FailureInterval 属性。
- 确保配置中绑定元素的所有超时值均设置为大于服务方法所用时间的值。
- 创建一个 ChannelFactory 并设置它的 Endpoint.Binding.SendTimeout 值。
- 确保在客户端和服务器上设置了 Compilation debug="false"(除非设置了此设置,否则不会正确遵守超时[不确定哪些超时])。
- 增加了 maxBufferSize、maxBufferPoolSize 和 maxReceivedMessageSize,尽管这应该与问题无关(服务器只是返回“hi mom”)。
- 在客户端代理上的代码中显式设置 SendTimeout(因为这应该是相关的超时)。
- 从控制台应用程序调用服务(相同的结果)。
我还能尝试什么?
[编辑] 将服务移至与 Web 应用程序相同的计算机,问题就消失了。
Running an MVC web site that calls a WCF service.
Site and service on 2 different machines.
.NET framework 4; IIS 7.
Production site is encountering a timeout when it should not. I created the simplest samples I could (simple web site that calls service method that returns "hi mom" after a delay) and was able to reproduce the problem. Here is how it goes:
- Client web app has it's binding's SendTimeout set to 6 minutes.
- Server service does nothing but write a message to a file, sleep for 5 minutes, write another message.
- Messages written to file on server are correct; server trace shows no problems.
- Client never receives return value from server service method. It's like it just loses it's connection to the server.
- Client throws TimeoutException after 6 minutes (any timeout greater than that just delays the exception further).
If I change the thread sleep time on the server to 4 minutes, everything works fine. This is repeatable, and there is nobody else messing with this test scenario.
So here is the pertinent config section of the client:
<binding name="BasicHttpBinding_IService1"
closeTimeout="00:6:00"
openTimeout="00:6:00"
receiveTimeout="00:6:00"
sendTimeout="00:6:00"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
messageEncoding="Text"
textEncoding="utf-8"
transferMode="Buffered"
useDefaultWebProxy="true">
<httpRuntime executionTimeout="1200"
maxRequestLength="10240" />
<serviceBehaviors>
<behavior>
<serviceTimeouts transactionTimeout="00:6:00" />
</behavior>
</serviceBehaviors>
The same values are present on the server.
Following include things I've tried:
- Added the serviceTimeouts element above.
- Ensured to call close on the client proxy class (even though that wouldn't be the issue in my case since the error happens every time).
- Created a channel explicitly, cast as IContextChannel and set OperationTimeout (as outlined here).
- Increased the FailureInterval property of the server's app pool in IIS.
- Ensured that all the timeout values of the binding element in the configs were all set to a value greater than the time taken by the service method.
- Created a ChannelFactory and set it's Endpoint.Binding.SendTimeout value.
- Ensured that Compilation debug="false" was set at client and server (read that timeouts [unsure which timeouts] not respected correctly unless this is set).
- Increased maxBufferSize, maxBufferPoolSize, and maxReceivedMessageSize even though this shouldn't have anything to do with the problem (the server simply returns "hi mom").
- Set SendTimeout explicitly in code on the client proxy (since this should be the relevant timeout).
- Called the service from a console app (same result).
What else can I try?
[Edit]
Moved the service to the same machine as the web app and the problem goes away.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是生产环境中防火墙上的 HTTP 策略:最大请求时间 5 分钟。
It was HTTP policy on firewall in production environment: max request time 5 minutes.