我正在研究一個wcf應用程序,我開始在它上面看到一個奇怪的超時行爲。 爲了確定問題是否與wcf有關,我創建了一個與真實應用程序具有相同配置的foo應用程序。負載測試期間的CommunicationException
客戶端應用程序代碼是這樣的:
public class Clients
{
public static void Main(string[] args)
{
var random = new Random();
var run = true;
var threads = 100;
for (int i = 0; i < threads; i++)
{
int delay = random.Next(1000, 1500);
var t = new Thread(() => {
var id = Guid.NewGuid().ToString("N").Substring(0, 10);
var client = new Client(@"client");
while (run)
{
Console.WriteLine(@"Sending thread id " + id);
client.Operation(@"Thread " + id);
Thread.Sleep(delay);
}
});
t.Start();
}
}
}
服務器應用程序代碼只記錄發送到控制檯的數據:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single,
IncludeExceptionDetailInFaults = true,
UseSynchronizationContext = false,
ValidateMustUnderstand = false)]
public class Service : IService
{
public void Operation(string data)
{
Console.WriteLine(@"Data received: {0}", data);
}
}
這是app.config文件:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="Test.Service" behaviorConfiguration="throttle">
<endpoint name="service"
address="net.tcp://localhost/service"
binding="netTcpBinding"
bindingConfiguration="NetTcpBinding"
contract="Test.IService"/>
</service>
</services>
<client>
<endpoint name="client"
address="net.tcp://localhost/service"
binding="netTcpBinding"
bindingConfiguration="NetTcpBinding"
contract="Test.IService"/>
</client>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding"
portSharingEnabled="true"
closeTimeout="00:01:00"
openTimeout="00:00:30"
receiveTimeout="00:00:10"
sendTimeout="00:00:10"
transactionFlow="false"
transferMode="Streamed"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="6553600"
maxBufferSize="6553600"
maxConnections="500"
maxReceivedMessageSize="6553600">
<readerQuotas maxDepth="128"
maxStringContentLength="3276800"
maxArrayLength="6553600"
maxBytesPerRead="1638400"
maxNameTableCharCount="6553600"/>
<security mode="None">
<transport protectionLevel="None"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="throttle">
<serviceThrottling maxConcurrentCalls="1000"
maxConcurrentInstances="10"
maxConcurrentSessions="500"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
如果同時運行應用程序和客戶端應用程序的線程數爲100沒關係。但是,如果我改變線程數到300,我得到以下異常:
System.ServiceModel.CommunicationException: The socket connection was aborted.
This could be caused by an error processing your message or a receive timeout
being exceeded by the remote host, or an underlying network resource issue.
Local socket timeout was '00:00:10'.---> System.Net.Sockets.SocketException:
An existing connection was forcibly closed by the remote host at
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32
offset, Int32 size, TimeSpan timeout, Boolean closing)
我使用的是四核機器上的端口共享和服務是自主辦。
這是同樣的問題,我在實際應用中,但具有更高的超時(2分鐘半)。我不能相信300是一個服務與InstanceContextMode.Single可以處理的最大連接數。我閱讀了有關缺省ChannelInitializationTimeout值(設置爲5)的問題,但我認爲這不是問題(在另一個測試中,我開始爲所有線程創建並打開一個客戶端,並等待6秒鐘以啓動所有線程線程,結果是10秒後相同的異常)。也許我正在以一種錯誤的方式配置一些東西。
如果有人有線索或想法,他們會有所幫助。提前致謝。
更新
我改變了從結合到netTcp和basicHttpBinding的,現在一切工作正常(無CommunicationExceptions拋出)。此外,我開始比以前更快地獲得服務中的消息,有誰知道爲什麼我使用basicHttpBinding獲得這種改進?
嘗試更新DefaultConnectionLimit屬性? http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx – 2012-04-18 18:11:06
@DavidZ。當服務是自託管時,此屬性是否有意義? – Diego 2012-04-18 18:13:25
是的,我相信特別是如果自我託管。值得一試。 – 2012-04-18 18:27:59