Rabbit MQ在WCF Web服务中的模型用法和性能

时间:2012-07-10 13:10:13

标签: c# wcf rabbitmq

我需要在IIS中托管的C#WCF Web服务中调用RabbitMQ RPC服务。 我们有这个工作正常,但作为一个优秀的小士兵我正在阅读RabbitMQ客户端文档,它声明以下“IModel不应该在线程之间共享”

我的理解是,在RabbitMQ中, IModel 实际上是一个套接字连接。 这意味着对于每次调用,WCF服务都需要创建一个IModel并在完成后对其进行处理。

在我看来,在性能和套接字使用方面有点过分,我想知道我的理解是否真的正确,或者是否有其他选项可用,比如在线程之间使用IModel连接池。

任何建议都会感激不尽。这是我在下面使用的代码示例,RabbitMQ连接实际上是在Global.asax中初始化的,我只是在那里你可以看到用法。

        var connectionFactory = new ConnectionFactory();
        connectionFactory.HostName = "SampleHostName";
        connectionFactory.UserName = "SampleUserName";
        connectionFactory.Password = "SamplePassword";
        IConnection connection = connectionFactory.CreateConnection();
        // Code below is what we actually have in the service method.
        var model = connection.CreateModel();
        using (model)
        {
            model.ExchangeDeclare("SampleExchangeName", ExchangeType.Direct, false);
            model.QueueDeclare("SampleQueueName", false, false, false, null);
            model.QueueBind("SampleQueueName", "SampleExchangeName", "routingKey" , null);
            // Do stuff, like post messages to queues
        }

2 个答案:

答案 0 :(得分:3)

  

IModel实际上是一个套接字连接

这是不正确的。 IConnection表示连接:)引入模型是为了允许多个客户端使用相同的tcp连接。因此,模型是“物理”连接的“逻辑”连接。

模型所做的任务之一是拆分和重新组装大型消息。如果消息超过一定大小,则将其拆分为帧,标记帧并由接收器组装回来。现在,想象一下,2个线程发送大量消息......帧号将被搞砸,你最终将得到Frankenstein消息,其中包含2个消息的随机部分。

你是正确的假设模型创建有一些成本。客户端向服务器发送请求以创建模型,服务器在内存中为此模型创建结构,并将模型ID发送回客户端。它是通过已打开的tcp连接完成的,因此不会因建立连接而产生开销。但由于网络往返,仍然存在一些开销。

我不确定WCF绑定,但base rabbit的.net库不为模型提供任何池。如果你的情况有问题,你必须自己想出一些东西。

答案 1 :(得分:1)

每个会话都需要一个IModel对象。对于基于网络的API来说,这是很正常的。例如,Azure表存储客户端完全相同。 为什么,您不能拥有一个通道,其中有多个并发通信流。

我希望发生一定程度的缓存(例如DNS),这将减少创建后续IModel实例的开销。

使用Azure Table执行相同操作时,性能是正常的,因此使用IModel应该完全没问题。只有当你能证明你有真正的需要时才尝试优化它。