为啥 MSMQ 比 WCF QueueService 快?
Posted
技术标签:
【中文标题】为啥 MSMQ 比 WCF QueueService 快?【英文标题】:Why is MSMQ faster than WCF QueueService?为什么 MSMQ 比 WCF QueueService 快? 【发布时间】:2012-07-03 17:35:57 【问题描述】:我在控制台中使用 netNamedPipeBinding
绑定自托管 WCF 服务。该服务只有一个空方法Send(DataTable bulk)
[ServiceContract]
public interface IWcfQueueService
[OperationContract]
void Send(DataTable bulk);
public class WcfQueueService : IWcfQueueService
public void Send(DataTable bulk)
// Here would be something like _bulks.Add(bulk);
// BUT, for now it is empty method and still it's slower than MSMQ
我的客户从 DB 获得 200K 输入并使用我们的 BoundedThreadPool 处理它(仅创建,比如说,20 个线程)。每个输入都用不同的线程处理。每个线程执行MyMethod
并在MyMethod
的末尾将结果添加到bulkManager
。
public void MyMethod(string input)
var res = ProcessInput(input);
bulkManager.Add(res);
当bulkManager
累积 N 项 (=bulk) 时,它将批量传递给另一个线程,它所做的只是使用以下两种方法之一将该批量加入队列:
-
如果启用 wcf:
wcfQueueService.Send(bulk);
如果启用了 MSMQ,则为:new MessageQueue(@".\private$\q").Send(new Message Body = bulk);
这两种方法都有效,但 MSMQ 的工作速度要快得多。使用 MSMQ 客户端可以在 20 秒内处理大约 80K 块,而使用 wcf 只能处理 20K-30K 块。 我不明白为什么会这样。我的 WCF 像 MSMQ 一样在不同的进程中运行。另外,我的 WCF 不存储任何东西,它有空方法。那么为什么 MSMQ 会赢得 WCF?
更新
正如leppie
建议的那样,我尝试了.NetRemoting。 NetRemoting 确实提高了速度。客户端处理了 60K。但是,
-
还是比 MSMQ 慢
当我阅读 .Net Remoting 已被 WCF 弃用时,根据this,WCF 应该比 .Net Remoting 更快,那么为什么我会发现我的 wcf 更慢?也许我的绑定有误?
【问题讨论】:
你可能会发现远程处理比 MSMQ 快很多(给定命名管道,我假设 IPC 在本地机器上)。 @leppie,.Net Remoting 确实提高了速度。客户端处理了 60K。但是,1 - 它仍然比 MSMQ 慢,2 - 当我读到 .Net Remoting 已被 WCF 弃用,根据msdn.microsoft.com/en-us/library/…,WCF 应该比 .Net Remoting 快,那么为什么我知道我的 wcf 更慢? @theateist:你能把服务上的InstanceContextMode
改成Single
和ConcurrencyMode
改成Multiple
吗?然后再做一次测试。也尝试调整节流设置(在服务行为中)。
@theateist:WCF 仅在非 IPC 方案中“替换”.NET 远程处理。 WCF 本质上是断开连接的,而远程处理“主要是连接的”。 .NET 远程处理永远不会消亡! :)
@leppie:来吧,伙计……你在说什么?它已经死了:)。
【参考方案1】:
我认为区别在于 WCF 操作中发生的情况与 MSMQ 在接受请求时所做的情况。
我希望当您使用 MSMQ simple 将消息排入队列时执行的方法会接受该消息,而不接受其他任何内容。一些后端工人负责繁重的工作。
在您的操作中,您需要将请求传递给请求处理程序的单例实例。当服务“启动”时,应该实例化请求处理程序实例。
您还可以通过使用 .NET 4 中的任务并行库来并行化您的请求来提高性能。
【讨论】:
【参考方案2】:您能否提供示例代码来显示您所看到的行为?
我通过生成 20,000 条要发送的消息进行了自己的测试。我尝试了两种方式,20,000 使用直接 MSMQ,20,000 使用 WCF 为我抽象 MSMQ 端点。
带有直接 MSMQ 的 20,000 使用了 64.75% 的 CPU 时间,而发送 20,000 条消息的 WCF 版本使用了 34.16% 的 CPU 时间(使用 Visual Studio Ultimate 的分析功能进行检测)。
除非我自己犯了错误,否则 WCF 版本的速度几乎是硬编码 MSMQ 版本的两倍。
【讨论】:
【参考方案3】:你不是在比较喜欢和喜欢。
最明显的区别是,在 WCF 案例中,您的时间包括执行整个服务端通道堆栈和操作调用,而您的直接 MSMQ 案例仅测量在客户端将有效负载排入队列的时间。请记住,WCF 中的服务端处理包括您的 DataTable 对象的反序列化,如果您的体积因子 N 很大,这可能会非常昂贵。
此外,根据您配置服务实例化和节流旋钮的方式,来自客户端的请求可能会比服务配置处理的速度更快,从而导致请求本身在队列中等待执行服务端。
此外,根据您配置绑定的方式,可能存在其他显着差异,例如安全性。顺便说一句,您是否真的使用 NetNamedPipeBinding (如您的问题所述)而不是标题似乎暗示的 NetMsmqBinding?如果是这样,使用默认绑定配置,您将拥有totally unnecessary 加密和签名每条批量消息,这在您的直接 MSMQ 案例中不会发生。这些对大型消息的加密操作也会相对昂贵。
与定义为 OneWay 的 WCF 操作进行更好的比较。
【讨论】:
那个“完全没有必要”的链接已经失效了,你有机会获得该条目的副本吗?真的有兴趣阅读,谢谢以上是关于为啥 MSMQ 比 WCF QueueService 快?的主要内容,如果未能解决你的问题,请参考以下文章
如何在使用 WCF 的事务性 MSMQ 中将消息显式标记为中毒