2012-04-18 109 views
1

我正在研究一個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獲得這種改進?

+1

嘗試更新DefaultConnectionLimit屬性? http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx – 2012-04-18 18:11:06

+0

@DavidZ。當服務是自託管時,此屬性是否有意義? – Diego 2012-04-18 18:13:25

+0

是的,我相信特別是如果自我託管。值得一試。 – 2012-04-18 18:27:59

回答

1

我發現這篇文章有好的建議和指標:High Performance WCF Services : netTcpBinding儘量遵循它,並使用最高性能WCF NetTcpBinding的配置。

一個實現最高性能配置的最相關的方面是運行在發佈客戶端和服務器。根據這篇文章,你可以比調試快29倍。

你也可以檢查此:

How fast are my services

祝你好運!

+0

我會試一試,讓你知道如果可行,謝謝! – Diego 2012-04-23 14:04:54

+0

我將構建配置更改爲在兩個應用程序中發佈,並使用第一個鏈接中的netTcpBinding配置,它工作正常!感謝您的鏈接! – Diego 2012-04-23 14:32:28