none
咨询WCF传输性能的问题 RRS feed

  • 问题

  • 概述:AB两个程序,它们通过WCFNetTcpBinding通讯,他们之间通过实体类对象(数据契约)通讯,目前性能是:

                 AB单向发数据无需返回值(void1分钟6万次数据的通信量

                 BA单向发数据有返回值(int1分钟6万次数据的通信量

                 两个同时发只能传输差不多各3万次,在A程序里写两个服务一个发一个收差不多也是各3万次。

     

    问题:怎么修改可以满足双向通讯1分钟20万次数据通信量或更高(补充:AB20万次数据,可以得到B程序20万次数据的应答)

     

    服务器配置:windows2008cpu:2*E5640 2.6GHz,内存:64G,硬盘:300*6 raid 5

     

    实体类:

        [DataContract]

        public class EntityMessage

        {

             /// <summary>

            /// 消息ID

            /// </summary>

            [DataMember]

            public string MessageID { get; set; }

           

            /// <summary>

            /// 加密方式

            /// </summary>

            [DataMember]

            public int EncryptMethod { get; set; }

     

            /// <summary>

            /// 校验码

            /// </summary>

            [DataMember]

            public string CheckCode { get; set; }       

     

            ......

        }

    配置文件:    

            <serviceBehaviors>      

                 <behavior>       

                   <serviceThrottling maxConcurrentCalls="20000" maxConcurrentInstances="20000" maxConcurrentSessions="20000" />        

                   <serviceMetadata httpGetEnabled="True" />               

                   <serviceDebug includeExceptionDetailInFaults="False" />  

                 </behavior>      

               </serviceBehaviors> 

            此处已经把maxConcurrentCallsmaxConcurrentInstancesmaxConcurrentSessions都配置成了20000.       

            <customBinding> 

                 <binding name="myCustomBinding">    

                   <reliableSession acknowledgementInterval="00:00:00.2000000" flowControlEnabled="true"  

                     inactivityTimeout="23:59:59" maxPendingChannels="16384" maxRetryCount="8" 

                     maxTransferWindowSize="4096" ordered="true" reliableMessagingVersion="Default" />      

                   <binaryMessageEncoding maxReadPoolSize="20000" maxWritePoolSize="20000"    

                     maxSessionSize="20480" />

                   <tcpTransport maxReceivedMessageSize="655360" maxBufferSize="655360" />      

                 </binding>        

               </customBinding>     

           此处已经把MaxTransferWindowSizemaxPendingChannels flowControlEnabled做了相应的配置

     

    服务配置:    

         [ServiceBehavior(UseSynchronizationContext = false, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]       

     

    服务调用:

    public class ServiceInvoker  

         {   

             private static Dictionary<string, ChannelFactory> channelFactories = new Dictionary<string, ChannelFactory>();     

             private static object syncHelper = new object();     

               

             private static ChannelFactory<TChannel> GetChannelFactory<TChannel>(string endpointConfigurationName)

             {        

                 ChannelFactory<TChannel> channelFactory = null;     

                 if (channelFactories.ContainsKey(endpointConfigurationName))        

                 {    

                     channelFactory = channelFactories[endpointConfigurationName] as ChannelFactory<TChannel>;        

                 }    

               

                 if (null == channelFactory)    

                 {    

                     channelFactory = new ChannelFactory<TChannel>(endpointConfigurationName);

                     lock (syncHelper)        

                     {

                         channelFactories[endpointConfigurationName] = channelFactory;      

                     }

                 }    

                 return channelFactory;

             }        

               

             public static void Invoke<TChannel>(Action<TChannel> action, TChannel proxy)  

             {        

                 ICommunicationObject channel = proxy as ICommunicationObject;  

                 if (null == channel)

                 {    

                     throw new ArgumentException("The proxy is not a valid channel", "proxy");

                 }    

                 try

                 {    

                     action(proxy);    

                 }    

                 catch (TimeoutException)    

                 {    

                     channel.Abort();        

                     throw;        

                 }    

                 catch (CommunicationException)

                 {    

                     channel.Abort();        

                     throw;        

                 }    

                 finally    

                 {    

                     channel.Close();         

                 }    

             }        

               

             public static TResult Invoke<TChannel, TResult>(Func<TChannel, TResult> function, TChannel proxy)         

             {        

                 ICommunicationObject channel = proxy as ICommunicationObject;  

                 if (null == channel)

                 {    

                     throw new ArgumentException("The proxy is not a valid channel", "proxy");

                 }    

                 try

                 {    

                     return function(proxy);      

                 }    

                 catch (TimeoutException)    

                 {    

                     channel.Abort();        

                     throw;        

                 }    

                 catch (CommunicationException)

                 {    

                     channel.Abort();        

                     throw;        

                 }    

                 finally    

                 {     

                     channel.Close();         

                 }    

             }        

               

             public static void Invoke<TChannel>(Action<TChannel> action, string endpointConfigurationName)  

             {        

                 Guard.ArgumentNotNullOrEmpty(endpointConfigurationName, "endpointConfigurationName");  

                 Invoke<TChannel>(action, GetChannelFactory<TChannel>(endpointConfigurationName).CreateChannel());  

             }        

               

             public static TResult Invoke<TChannel, TResult>(Func<TChannel, TResult> function, string endpointConfigurationName)        

             {        

                 Guard.ArgumentNotNullOrEmpty(endpointConfigurationName, "endpointConfigurationName");  

                 return Invoke<TChannel, TResult>(function, GetChannelFactory<TChannel>(endpointConfigurationName).CreateChannel());        

             } 

         }


    • 已编辑 翟雷兵 2014年1月16日 6:45 描述有歧义
    2014年1月16日 2:28

答案

  • A程序调用B程序20万次,B程序同时调用20万次A,每秒单向3300次,目前测试只有一个EntityMessage,实体类中有30多个属性,属性赋值。
    实际应用是:A调用B程序20万次,B每次把收到的信息处理后生成新的实体类发送给A程序,数据不延时。

    A -〉B :设置为 OneWay;

    B -> A : 使用异步发送。

    2014年1月16日 6:57

全部回复

  • 你的 20 万数据是啥意思?

    是调用服务 20 万次,还是在一次服务调用中传输 20 万个 EntityMessage或 20万字节数据?

    2014年1月16日 3:27
  • A程序调用B程序20万次,B程序同时调用20万次A,每秒单向3300次,目前测试只有一个EntityMessage,实体类中有30多个属性,属性赋值。
    实际应用是:A调用B程序20万次,B每次把收到的信息处理后生成新的实体类发送给A程序,数据不延时。

    2014年1月16日 6:43
  • A程序调用B程序20万次,B程序同时调用20万次A,每秒单向3300次,目前测试只有一个EntityMessage,实体类中有30多个属性,属性赋值。
    实际应用是:A调用B程序20万次,B每次把收到的信息处理后生成新的实体类发送给A程序,数据不延时。

    A -〉B :设置为 OneWay;

    B -> A : 使用异步发送。

    2014年1月16日 6:57