【问题标题】:WCF performance vs simple ASP.NET HttpHandlerWCF 性能与简单的 ASP.NET HttpHandler
【发布时间】:2012-01-17 14:27:54
【问题描述】:

TL;DR ver:WCF 服务的行为(尽管它似乎配置为 HTTP 上的最大吞吐量)比简单的 ASP.NET 处理程序实现慢 4 倍


更新1

切换到release模式和IIS(full not express)7.5改号:

  • ASP.NET:从 15 秒到 6.7 秒
  • WCF:从 60 秒到 13.7 秒

详细解释:

我一直在寻找一种有效的方法来在两台不同的物理机器之间的 Intranet 中快速传输信息(命名管道毫无疑问)。我的通信合约由以下操作组成:

void SetUserAsState1(int id);
void SetUserAsState2(int id);
byte GetUserState(int id);

我会说很简单。我不会考虑安全性、可靠性等。只是纯粹的性能。性能是指每秒可以发送多少请求到另一台机器。

我在我的笔记本电脑上做了两种情况的测试:

  • 一个带有通用 GetData.ashx 处理程序的 ASP.NET 空网站,可以像 http://localhost:1234/GetData.ashx?op=1&id=239 一样调用它(IIS Express 已经使用)
  • 使用 basicHttpBinding 在 IIS (Express) 中托管的 WCF 服务

我是如何测试的?我设置了 10 个线程,每个线程将对目标执行 1000 个请求,并测量完成所有 10x1000=10,000 个请求所需的时间。

结果?

  • ASP.NET:15 秒
  • WCF:60 秒

测试工具:(不,这不是生产质量)

class Program
{
    private static Service1Client _wcfProxy;

    static void Main()
    {
        _wcfProxy = new Service1Client();
        _wcfProxy.GetData(); // warm up proxy and service
        _wcfProxy.GetData(); // make it really warm :P

        var threads = new Thread[10];
        for (var cnt = 0; cnt < 10; cnt++)
        {
            //var t = new ThreadStart(TestAspnetHandler); // scenario 1
            var t = new ThreadStart(TestWcfService); // scenario 2
            (threads[cnt] = new Thread(t)).Start();
        }
        var sw = Stopwatch.StartNew();
        foreach (var thread in threads)
        {
            thread.Join();
        }
        sw.Stop();
        Console.WriteLine("Done 10 x 1000 calls in " + sw.Elapsed);
        Console.ReadLine();
    }

    private static void TestAspnetHandler()
    {
        var webClient = new WebClient();
        for (var i = 0; i < 1000; i++)
        {
            webClient.DownloadData("http://localhost:1970/GetData.ashx?id=1");
        }
    }

    private static void TestWcfService()
    {
        for (var i = 0; i < 1000; i++)
        {
            _wcfProxy.GetData();
        }
    }
}

ASP.NET 实现:

public class GetData : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        var id = context.Request.QueryString["id"];
        if (string.IsNullOrEmpty(id))
        {
            context.Response.Write("Hello World");
        }
        else
        {
            var identifier = int.Parse(id);
            context.Response.Write(identifier * 23);
        }
    }

    public bool IsReusable { get { return true; } }
}

默认 4.0 配置,无变化


WCF 合同:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    int GetData();
}

和实施

[ServiceBehavior(
    ConcurrencyMode = ConcurrencyMode.Multiple, 
    InstanceContextMode = InstanceContextMode.Single)]
public class Service1 : IService1
{
    public int GetData()
    {
        return 23;
    }
}

和配置:

<services>
  <service behaviorConfiguration="beh" name="IService1">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttp" 
              contract="WcfService1.IService1" />
  </service>
</services>

<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" allowCookies="false" />
  </basicHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="beh">
      <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="false"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />


我已将并发模式设置为多个(因此它们不会同步)、单个服务实例化、节流设置为高值,不知道是否/如何才能加快 WCF 服务的速度。 WCF 服务是否会赶上 ASP.NET 服务(即通过 HTTP 实现)?

【问题讨论】:

    标签: asp.net wcf performance http httphandler


    【解决方案1】:

    Tcp 出问题了? 您可以从序列化中获得更多性能 - 尝试 NetDataContractSerialization 或 protobuf.net。您可以缓存通道工厂 - 因此无需添加服务引用。

    【讨论】:

    • 不,NetTcpBinding 不是不可能的。我在设置它时有些头疼,我暂时发送到 pzd_ms。加上 basicHttpBinding 提供了与 ASP.NET 的更均匀的比较。
    • 如果所有其他选项都用完了,我稍后会尝试 TCP :)
    • 还有一个我忘记在服务器上的设置 - 与启用 gc 相关的smth。在生产环境中,使用异步 WCF、默认序列化、使用 netTcp 并且没有安全性(是的,生产,没有给出名称 shhhh)我在客户端和服务器之间有 40-50 毫秒的往返时间。由于 netTcp 激活,第一个请求持续了一点时间,但之后就轻而易举了。
    猜你喜欢
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 2011-06-28
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 2015-05-26
    相关资源
    最近更新 更多