TL;DR ver:WCF 服务行为(虽然它似乎配置为 HTTP 上的最大吞吐量)比原始 ASP.NET 处理程序实现慢 4 倍
更新 1:
切换到 Release模式和 IIS(完全不是 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 契约(Contract):
[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 服务是否有任何变化可以 catch ASP.NET 服务(即通过 HTTP 实现)?
最佳答案
tcp出问题了? 您可以从序列化中获取更多性能 - 尝试 NetDataContractSerialization 或 protobuf.net。您可以缓存 channel 工厂 - 因此无需添加服务引用。
关于asp.net - WCF 性能与简单的 ASP.NET HttpHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8460013/