我们有一个在 Windows Server 2008 R2 虚拟机上运行的 WCF 数据收集服务。客户端是 Win 7 x64 机器,应用程序是 C# .NET 4 Windows 窗体应用程序。该服务的主要目的是从客户端收集测试结果并根据该数据提供报告。(它连接到 SQL Server 实例和 Oracle 实例,但这可能无关紧要。)
最近,随着我们添加更多客户端,我们开始看到数据传输丢失,并且服务端出现“MaxOutboundConnectionsPerEndpoint quota (10)”错误,因此我们相应地调整了参数。
这种类型的错误消失了,但现在我们在服务器端收到“Faulted System.ServiceModel.Channels.ServerSessionPreambleConnectionReader+ServerFramingDuplexSessionChannel”错误。在服务器端运行 WireShark 被证明是徒劳的,因为它不会继续运行……也许虚拟机受到干扰,我不知道。
在客户端运行 WireShark 会产生更多信息。当发送失败发生时,WireShark 报告了几个“TCP Window Full”错误。
这是来自服务器端的绑定定义:
<bindings>
<netTcpBinding>
<binding name="bigBufferBinding"
portSharingEnabled="false"
maxBufferSize="1024000"
maxBufferPoolSize="1000000"
maxReceivedMessageSize="1024000"
maxConnections="500"
listenBacklog="250"
sendTimeout="00:05:00"
receiveTimeout="00:05:00">
<readerQuotas maxDepth="200"
maxStringContentLength="65536"
maxArrayLength="32768"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
这是客户端:
<bindings>
<netTcpBinding>
<binding name="bigBuffer_ClientTcpBinding"
maxBufferSize="1024000"
maxBufferPoolSize="1000000"
maxReceivedMessageSize="1024000"
sendTimeout="00:00:30"
receiveTimeout="00:00:30">
<readerQuotas maxDepth="200"
maxStringContentLength="65536"
maxArrayLength="32768"
maxBytesPerRead="4096"
maxNameTableCharCount="16384"/>
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
我尝试增加 maxBufferSize、maxBufferPoolSize 和 maxReceivedMessageSize 属性,但任何显着增加都会导致服务无法启动。无论如何,我不确定这就是问题所在。
我需要在这里看什么?我们没有大量数据(10 个客户端偶尔向服务发送 60 到 40000 字节的数据),所以我们当然不应该压倒 WCF 服务。我认为这与 TCP 的配置方式有关,但这只是猜测。它在禁用巨型数据包的千兆网络上运行。
在数千次尝试中,我们每天有 15 到 40 次数据失败。我们添加了重试,因此数据最终到达那里(在大多数情况下是第二次尝试)——这并不能真正解决问题,但它让我无法生产,我们实际上并没有丢失任何数据。
只是为了平息预期的抗议和责骂,我们正在将序列化的数据写入失败的磁盘文件(两次!),因此如果数据无法进入数据库,我们可以重新提交它。我们实际上从未丢失任何数据。
想法?任何帮助表示赞赏,可根据要求提供更多数据。
谢谢,戴夫