简体   繁体   English

WCF往返时间很差,线程更多

[英]Very Bad WCF round trip time with more threads

I have written a WCF application where client, server runs on the same machine. 我编写了一个WCF应用程序,其中客户端服务器在同一台计算机上运行。 With few threads (<10) the average roundtrip time (client -> server -> client) is 400 milli sec. 如果线程数较少(<10),则平均往返时间(客户端->服务器->客户端)为400毫秒。 If I increase the threads to 200 then the average roundtrip time increases to 50 sec. 如果将线程数增加到200,则平均往返时间将增加到50秒。

My WCF service is using basicHttp, Per-call, concurrent with 500 connections. 我的WCF服务使用basicHttp,按呼叫,并发500个连接。 Service is hosted in a console. 服务托管在控制台中。 Client is using the interface and communicates with service by opening a Channel using ChannelFactory. 客户端正在使用该接口,并通过使用ChannelFactory打开Channel与服务进行通信。 The data exchanged between server, client is at most 5 MB. 服务器与客户端之间交换的数据最大为5 MB。

Server app.config 服务器app.config

<system.serviceModel>
<behaviors>
  <serviceBehaviors>
    <behavior name="serviceBehavior1">
      <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:3999/TestWCFService/" httpsGetEnabled="false" httpsGetUrl="https://http://localhost:3999/TestWCFService/"/>
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" maxConcurrentInstances="500" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" openTimeout="02:00:00" receiveTimeout="21:00:00" sendTimeout="21:00:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
      <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" />
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service behaviorConfiguration="serviceBehavior1" name="TestWCF.TestWCFServer">
    <endpoint address="http://localhost:3999/TestWCFService/" binding="basicHttpBinding" bindingConfiguration="basicHttp"
      name="TestWCFServiceEndpoint" contract="TestWCF.ITestWCFInterface">
      <identity>  <dns value="localhost"/>  </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
        <baseAddresses>  <add baseAddress="http://localhost:3999/TestWCFService/"/> </baseAddresses>
    </host>
  </service>
</services>

Server Code (The arguments Geometry, EntityDataFilter are defined in a separate DLL which is added as a reference in both client, server) 服务器代码(参数Geometry,EntityDataFilter在单独的DLL中定义,该DLL被添加为客户端和服务器中的引用)

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
internal class TestWCFServer : ITestServiceInterface
{
  public IList<EntityData> fetchEntityData(Geometry boundary, EntityDataFilter filter, string clientID)
  {
    // Fetch the EntityData from database inmemory cache with the given inputs.
    // I have a timer inside the whole method. This whole method is taking ~4 milli seconds.
  }
}

// Main class that starts the server
public static class TestWCFMain
{
  static void Main()
  {
    using (ServiceHost host = new ServiceHost(typeof(VSCacheService)))
    {
        host.Open();
        Log.Info("Server is UP !!!");
        Log.Info("<Press enter to shutdown server>");               

        Console.ReadLine();
    }
  }
}

Client app config 客户端应用配置

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" openTimeout="02:00:00" receiveTimeout="21:00:00" sendTimeout="21:00:00"
           maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
       <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" />
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:3999/TestWCFService/" binding="basicHttpBinding"
      bindingConfiguration="basicHttp" contract="TestWCF.ITestWCFInterface" name="TestWCFServiceEndpoint" kind="" endpointConfiguration="" />
</client>

Client Code (The arguments Geometry, EntityDataFilter are defined in a separate DLL which is added as a reference in both client, server) 客户端代码(参数Geometry,EntityDataFilter在单独的DLL中定义,该DLL被添加为客户端和服务器中的引用)

void fetchEntityDataFromServer(Geometry boundary, EntityDataFilter filter, string clientID)
{
    var channelFactor = new ChannelFactory<ITestWCFInterface>("TestWCFServiceEndpoint");
    channelFactor.Open();

    var proxy = channelFactor.CreateChannel();

    IList<EntityData> res = proxy.fetchEntityData(Geometry boundary, EntityDataFilter filter, string clientID);
}

I am stuck here. 我被困在这里。 Any pointers to move forward will be a great help. 任何前进的指针都会有很大的帮助。 Thanks in advance.. 提前致谢..

I perform some tests with 200 threads with my WCF service. 我使用WCF服务对200个线程执行了一些测试。 Client and service are placed on the same OS. 客户端和服务位于同一操作系统上。

Client: 200 threads with 20 x call to service method 客户端: 200个线程,其中20个调用服务方法

Service: 服务:

  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

  <wsHttpBinding>
    <binding name="WSHttpBinding" sendTimeout="00:00:30" transactionFlow="false" maxReceivedMessageSize="2147483647">
      <security mode="None">
        <message clientCredentialType="None" establishSecurityContext="false" negotiateServiceCredential="false" />
        <transport clientCredentialType="None" />
      </security>
    </binding>
  </wsHttpBinding>

Results for different service method variants 不同服务方法变体的结果

  1. Thread.Sleep(10) 线程睡眠(10)

    • Average client response time: ~11ms 客户端平均响应时间:〜11ms
  2. 1MB response of random string 1MB随机字符串的响应

    • Average response time: ~1.5min 平均回应时间:〜1.5分钟
    • CPU usage: ~90-93% CPU使用率:〜90-93%
  3. 1MB response of const string 1MB const字符串响应

    • Average response time: ~450ms 平均响应时间:〜450ms
    • CPU usage: ~75-80% CPU使用率:〜75-80%
  4. 5MB response of random string 5MB随机字符串的响应

    • Average response time: ~6min 平均响应时间:〜6min
    • CPU usage: ~95-99% CPU使用率:〜95-99%
  5. 5MB response of const string 5MB const字符串响应

    • Average response time: ~1,7min 平均响应时间:〜1,7min
    • CPU usage: ~75-80% CPU使用率:〜75-80%

Suspicions: Each call = 5MB response ? 怀疑:每个呼叫= 5MB响应? If yes then it sounds like a lot of data to serialize/transfer. 如果是,那么听起来要序列化/传输很多数据。 In my opinion it's just hardware limitation. 我认为这仅仅是硬件限制。

Suggestions: 意见建议:

  1. Do not open factory. 不要开工厂。 channelFactory.Open()
  2. Check channel factory cache option or cache it by yourself. 检查通道工厂缓存选项或自己缓存。
  3. Try another bindings ...even theoretically slower wsHttpBinding with security mode="None" 尝试另一个绑定...在security mode="None"甚至理论上更慢的wsHttpBinding
  4. If client and server are running on the same OS then try NetNamedPipeBinding . 如果客户端和服务器在同一操作系统上运行,请尝试NetNamedPipeBinding

You should try increasing the number of concurrent connections from the client code that WCF sets up. 您应该尝试从WCF设置的客户端代码中增加并发连接的数量。 i think threads are waiting until a connection can be setup thus increasing the average throughput. 我认为线程正在等待直到可以建立连接,从而增加了平均吞吐量。

See this post for and example: Multiple concurrent WCF calls from single client to Service 有关示例,请参阅此帖子: 从单个客户端到服务的多个并发WCF调用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM