【问题标题】:RabbitMQ in a WCF webservice, model usage and performanceWCF webservice中的RabbitMQ,模型使用和性能
【发布时间】:2012-07-10 13:10:13
【问题描述】:

我需要从托管在 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
        }

【问题讨论】:

    标签: c# wcf rabbitmq


    【解决方案1】:

    IModel其实是一个socket连接

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

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

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

    我不确定 WCF 绑定,但基本 rabbit 的 .net 库不提供任何模型池。如果这对你来说是个问题,你必须自己想出一些办法。

    【讨论】:

    • 感谢 Vadmin,这是我需要的信息。我不太担心模型管理的开销;只需使用一次 Rabbit .NET 客户端就不必在每个请求上都创建一个套接字。我知道这是一项密集的手术。
    【解决方案2】:

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

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

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

    【讨论】:

    • 感谢阿利斯泰尔的更新。我假设我所做的与 WCF 使用的单次使用代理模式非常相似。我不确定兔子库实际上会在哪里缓存连接。或者如果这是操作系统的操作。至于性能;事情似乎在我们的环境中运行良好。我更担心外部托管环境以及在那里我们几乎不知道或控制系统运行的问题的可能性。所以只是想尽我所能挤出最后一点可能的表现。干杯诺尔。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-14
    • 2010-11-29
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    相关资源
    最近更新 更多