gpt4 book ai didi

.net - 当可靠 session 打开并且突发异步请求时,WCF 很慢

转载 作者:行者123 更新时间:2023-12-02 00:16:06 25 4
gpt4 key购买 nike

对于实验,我在 VS2012 上使用 .NET 4.5 创建了一个简单的“Hello World”WCF 服务和客户端。服务器托管在控制台应用程序上并使用 net.tcp 绑定(bind)。我编写了客户端代码来向服务器发送大量异步请求(总共 700 个请求)。一切都很顺利,直到我打开服务的可靠 session 功能。开启后,服务突然跑得很慢,在我的机器上花了将近一分钟才完成 700 个请求。我尝试微调 Concurrency 和 Throttling 参数(见下文),但没有帮助。

有谁知道为什么会这样?有没有办法避免这种情况?

如果我关闭了 Reliable session 功能,或者我使服务调用同步,则不会发生缓慢。所以我认为这可能与 WCF 在 WS-ReliableMessaging 模式下处理挂起请求的方式有关。

编辑:当我将 netTcpBinding 更改为 wsHttpBinding 时,这也没有发生。这很奇怪,因为在这种情况下 wsHttpBinding 比 netTcpBinding 快得多。

编辑:在服务器端运行 Perfmon.exe 表明在上述情况下,“线程数”逐渐从 8 增加到 100 以上。

编辑:我的电脑(本地网络)上的一些测量吞吐量。看到案例 1 的性能非常缓慢并且几乎没有用处。

  • 异步 + NetTcpBinding/可靠吞吐量 -> 大约。 14 次调用/秒(70 毫秒/次调用)
  • 异步 + WsHttp/可靠吞吐量 -> 7957 call/s (0.12 ms/call)
  • 同步 + NetTcpBinding/可靠吞吐量 -> 3986 call/s (0.25 ms/call)

  • 下面是我在实验中使用的服务器和客户端的代码和配置。

    服务器:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    using System.ServiceModel;
    using System.ServiceModel.Description;

    [ServiceContract]
    public interface IHelloService
    {
    [OperationContract(IsOneWay=false)]
    string SayHello(string name);
    }

    [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple, InstanceContextMode=InstanceContextMode.PerSession)]
    public class HelloService : IHelloService
    {
    public string SayHello(string name) {
    String s = string.Format("Hello {0}", name);
    return s;
    }
    }

    namespace WcfServer
    {
    class Program
    {
    static void Main(string[] args)
    {
    Uri baseAddress = new Uri("net.tcp://localhost:8080/hello");
    using (ServiceHost host = new ServiceHost(typeof(HelloService), baseAddress)){
    // Open and listen
    host.Open();
    Console.WriteLine("The service is ready at {0}", baseAddress);
    Console.WriteLine("Press <Enter> to stop the service.");
    Console.ReadLine();
    // Close the ServiceHost.
    host.Close();
    }
    }
    }
    }

    客户:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    using System.ServiceModel;
    using WcfClient.WcfServer;

    namespace WcfClient
    {
    class Program
    {
    static async Task PrintNameAsync(HelloServiceClient client, int cnt) {
    string s = await client.SayHelloAsync(string.Format("-- {0} --", cnt));
    Console.WriteLine(s);
    }

    static void Main(string[] args)
    {
    HelloServiceClient client = new HelloServiceClient("HelloService", "net.tcp://10.20.61.13:8080/hello");
    List<Task> tasks = new List<Task>();
    for(int i=0; i < 700; i++){
    Task t = PrintNameAsync(client, i);
    tasks.Add(t);
    }
    Task.WhenAll(tasks).Wait();
    client.Close();
    }
    }
    }

    服务器的 App.config:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
    <bindings>
    <netTcpBinding>
    <binding name="HelloServiceBinding">
    <reliableSession ordered="true" enabled="true" />
    <security mode="None" />
    </binding>
    </netTcpBinding>
    </bindings>
    <behaviors>
    <serviceBehaviors>
    <behavior name="HelloServiceBehavior">
    <serviceMetadata policyVersion="Policy15" />
    <serviceDebug includeExceptionDetailInFaults="true" />
    <serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000"
    maxConcurrentInstances="1000" />
    </behavior>
    </serviceBehaviors>
    </behaviors>
    <services>
    <service behaviorConfiguration="HelloServiceBehavior" name="HelloService">
    <endpoint address="net.tcp://localhost:8080/hello" binding="netTcpBinding"
    bindingConfiguration="HelloServiceBinding" name="HelloService" contract="IHelloService" />
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
    </service>
    </services>
    </system.serviceModel>
    </configuration>

    客户端的 App.config:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <system.serviceModel>
    <bindings>
    <netTcpBinding>
    <binding name="HelloServiceBinding" sendTimeout="00:01:00">
    <reliableSession enabled="true" />
    <security mode="None" />
    </binding>
    </netTcpBinding>
    </bindings>
    <client>
    <endpoint address="net.tcp://localhost:8080/hello" binding="netTcpBinding"
    bindingConfiguration="HelloServiceBinding" contract="WcfServer.IHelloService"
    name="HelloService">
    </endpoint>
    </client>
    </system.serviceModel>
    </configuration>

    最佳答案

    从以下链接中找到了该问题的部分解决方法:

  • http://blogs.msdn.com/b/endpoint/archive/2011/05/04/wcf-scales-up-slowly-with-bursts-of-work.aspx
  • http://support.microsoft.com/kb/2538826

  • 使用解决方法(使用 WorkerThreadPoolBehavior),测得的吞吐量如下:
  • Async + NetTcpBinding/Reliable 吞吐量 -> 474 call/s (2.1 ms/call) ... 改进但不令人满意
  • 异步 + WsHttp/可靠吞吐量 -> 7856 call/s (0.13 ms/call) ... 没有变化
  • 同步 + NetTcpBinding/可靠吞吐量 -> 2110 call/s 0.47 ms/call) ... 降级

  • 请注意,上述案例 1 比 70 毫秒/调用显着提高。但是,它仍然落后于案例 2。对于案例 3,引入 WorkerThreadPool 行为会导致性能从 0.25 毫秒/调用下降到 0.47 毫秒/调用。

    关于.net - 当可靠 session 打开并且突发异步请求时,WCF 很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13028717/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com