13

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)时,它将批量传递给另一个线程,它所做的只是使用以下两种方法之一将该批量加入队列:

  1. 如果启用了 wcf:wcfQueueService.Send(bulk);
  2. 否则,如果启用了 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。但,

  1. 它仍然比 MSMQ 慢
  2. 当我读到 .Net Remoting 已被 WCF 弃用时,WCF 应该比 .Net Remoting 快,那么为什么知道我的 wcf 更慢?也许我的绑定是错误的?
4

3 回答 3

4

你不是在比较喜欢和喜欢。

最明显的区别是,在 WCF 案例中,您的时间包括整个服务端通道堆栈和操作调用的执行,而您的直接 MSMQ 案例仅测量在客户端排队有效负载的时间。请记住,WCF 中的服务端处理包括您的 DataTable 对象的反序列化,如果您的体积因子 N 很大,这可能会非常昂贵。

更重要的是,根据您配置服务实例化和节流旋钮的方式,来自客户端的请求可能比服务配置处理的速度更快,导致请求本身在服务端排队等待执行。

此外,根据您配置绑定的方式,可能存在其他显着差异,例如安全性。顺便说一句,您是否真的使用 NetNamedPipeBinding (如您的问题所述)而不是标题似乎暗示的 NetMsmqBinding?如果是这样,使用默认绑定配置,您将完全不必要地加密和签署每条批量消息,这在您的直接 MSMQ 案例中不会发生。这些对大消息的加密操作也将相对昂贵。

与定义为 OneWay 的 WCF 操作进行更好的比较。

于 2012-07-22T12:15:59.530 回答
1

您能否提供示例代码来显示您所看到的行为?

我通过生成 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 版本的两倍。

于 2012-07-09T01:37:26.527 回答
0

我认为不同之处在于您的 WCF 操作与 MSMQ 在接受请求时所做的事情。

我希望当您使用 MSMQ simple 将消息排入队列时执行的方法只接受该消息而不接受其他任何内容。一些后端工人负责繁重的工作。

在您的操作中,您需要将请求传递给请求处理程序的单例实例。当服务“启动”时,应该实例化请求处理程序实例。

您还可以通过使用 .NET 4 中的任务并行库来并行化您的请求来提高性能。

于 2012-07-04T23:48:10.250 回答