我有一个客户端服务器应用程序。我的情况:
有时WCF连接更改为故障状态。通常,发生这种情况时,服务器根本没有上游网络。我确实编写了一个内存转储,并且能够看到许多WCF线程正在等待某些WaitQueue
。调用堆栈为:
Server stack trace:
at System.ServiceModel.Channels.TransmissionStrategy.WaitQueueAdder.Wait(TimeSpan timeout)
at System.ServiceModel.Channels.TransmissionStrategy.InternalAdd(Message message, Boolean isLast, TimeSpan timeout, Object state, MessageAttemptInfo& attemptInfo)
at System.ServiceModel.Channels.ReliableOutputConnection.InternalAddMessage(Message message, TimeSpan timeout, Object state, Boolean isLast)
at System.ServiceModel.Channels.ReliableDuplexSessionChannel.OnSend(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.DuplexChannel.Send(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.DuplexChannelBinder.Send(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
我确实对设置进行了调整,但情况似乎有所缓解-现在故障更少的客户。我的设置:
我被困住了。为什么所有呼叫都尝试等待WaitQueue
中的某个TransmissionStrategy
?我不在乎邮件是否乱码发送(我自己会照顾的)。我已经在考虑禁用可靠的消息传递,但是该应用程序已在全球的公司网络中使用。我需要知道我的邮件已经发送。
有什么想法可以教WCF仅发送消息而不关心其他事情吗?
编辑
服务限制的值设置为Int32.MaxValue
。
我也曾尝试将MaxConnections
上的ListenBackLog
和NetTcpBinding
设置为最大值。据我所知,它并没有改变任何东西。
编辑2
检查WCF跟踪会告诉我(德语消息,因此为粗略翻译),可靠消息传递窗口中没有可用空间-然后我得到的都是超时,因为没有更多消息被发送。
那里发生了什么?可靠的消息传递有可能使自己困惑吗?
答案 0 :(得分:2)
等待队列可以与内置节流行为https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/servicethrottling的wcf相关 解决问题的最佳方法是启用wcf跟踪 https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/servicethrottling 并确切地知道根本原因是什么
答案 1 :(得分:1)
是否使用connectionManagement设置客户端的最大连接?(如果会话是双工的) https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/network/connectionmanagement-element-network-settings
您的MaxPendingChannels设置为16384,这会使太多的客户端在队列中等待,如果服务器无法及时处理客户端,则通道可能会变为故障状态。
FlowControlEnabled表示当服务器没有剩余空间来保存消息时是否继续向服务器端发送消息。您最好将其设置为true。
InactivityTimeout表示在一定时间内没有消息交换时是否关闭会话。您最好将其设置为合适的值。
此外,您是否设置了绑定的超时时间?
<netTcpBinding>
<binding closeTimeout="" openTimeout="" receiveTimeout="" sendTimeout="" ></binding>
</netTcpBinding>
答案 2 :(得分:1)
长话短说:
事实证明,我的WCF设置还可以。
ThreadPool是限制因素。在高流量(因此负载很高)的情况下,我确实会生成大量必须发送到客户端的消息。由于没有足够的工作线程来发送消息,因此将它们排队。在某个时候,队列已满-在那里。
有关更多详细信息,请查看Russ Bishop的question & answer。
有趣的细节:在交通繁忙的情况下,这甚至降低了CPU负载。从30%到80%的疯狂涨幅到30%左右的(几乎)稳定值。我只能假定这是由于线程池线程的生成和清理。
编辑
我做了以下事情:
ThreadPool.SetMinThreads(1000, 500)
该值可能类似于使用大锤开裂螺母-但它可以工作。