4

我需要从 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
        }
4

2 回答 2

3

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

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

Model 所做的任务之一是拆分和重新组装大型消息。如果消息超过一定大小,则将其拆分为帧,帧被标记并由接收者组装回来。现在,假设 2 个线程发送大消息......帧号会被弄乱,你最终会得到由 2 条消息的随机部分组成的 Frankenstein 消息。

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

我不确定 WCF 绑定,但基本 rabbit 的 .net 库不为模型提供任何池。如果您的情况有问题,您将不得不自己想出一些办法。

于 2012-07-31T16:49:54.707 回答
1

每个会话都需要一个 IModel 对象。这对于基于网络的 API 来说是很正常的。例如 Azure 表存储客户端是完全一样的。为什么,你不能有一个单一的通道,其中有多个并发的通信流在它们上面运行。

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

使用 Azure Tables 执行相同操作时性能还可以,因此使用 IModel 应该非常好。只有当你能证明你有真正的需要时,才尝试优化它。

于 2012-07-30T11:19:04.087 回答