我需要在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
}
答案 0 :(得分:3)
IModel实际上是一个套接字连接
这是不正确的。 IConnection表示连接:)引入模型是为了允许多个客户端使用相同的tcp连接。因此,模型是“物理”连接的“逻辑”连接。
模型所做的任务之一是拆分和重新组装大型消息。如果消息超过一定大小,则将其拆分为帧,标记帧并由接收器组装回来。现在,想象一下,2个线程发送大量消息......帧号将被搞砸,你最终将得到Frankenstein消息,其中包含2个消息的随机部分。
你是正确的假设模型创建有一些成本。客户端向服务器发送请求以创建模型,服务器在内存中为此模型创建结构,并将模型ID发送回客户端。它是通过已打开的tcp连接完成的,因此不会因建立连接而产生开销。但由于网络往返,仍然存在一些开销。
我不确定WCF绑定,但base rabbit的.net库不为模型提供任何池。如果你的情况有问题,你必须自己想出一些东西。
答案 1 :(得分:1)
每个会话都需要一个IModel对象。对于基于网络的API来说,这是很正常的。例如,Azure表存储客户端完全相同。 为什么,您不能拥有一个通道,其中有多个并发通信流。
我希望发生一定程度的缓存(例如DNS),这将减少创建后续IModel实例的开销。
使用Azure Table执行相同操作时,性能是正常的,因此使用IModel应该完全没问题。只有当你能证明你有真正的需要时才尝试优化它。