C# RabbitMQ 客户端线程安全性

16
ConnectionFactory factory = new ConnectionFactory {HostName = "localhost"};

using (IConnection connection = factory.CreateConnection())
using (IModel channel = connection.CreateModel())
{
    channel.QueueDeclare("hello", false, false, false, null);
    for (int i = 0; i < 100000; i++)
    {
        MemoryStream stream = new MemoryStream();

        var user = new User 
                       {
                           Id = i
                       };

        Serializer.Serialize(stream, user);


        channel.BasicPublish("", "hello", null, stream.ToArray());

    }

}

我有上面的代码,我很担心它的线程安全性。

我不确定,但我想象ConnectionFactory是线程安全的。但是IConnection是否线程安全?我应该每个请求创建一个连接,还是一个单独的持久化连接?那么通道(IModel)又是如何呢?

此外,我应该将连接存储为ThreadLocal吗?还是应该每个请求创建一个连接?


1
请查看我对这个问题的回答https://dev59.com/kmkv5IYBdhLWcg3wtS8N#10501593。 - robthewolf
1个回答

44

IConnection是线程安全的,而IModel则不是。通常情况下,您应该努力让连接在应用程序的整个生命周期中保持打开状态,尤其是如果您有消费者需要一个开放的连接来接收消息时。检测和恢复中断的连接非常重要,这可能是由于网络或代理器故障引起的。我建议阅读 Videla 和 Williams 的《RabbitMQ in Action》尤其是第六章“编写能够经受住失败的代码”。

现在为了公关一下自己,我是EasyNetQ的作者,它是一个适用于RabbitMQ的高级.NET API。它会为您处理所有的连接管理,并且如果出现网络或代理故障,它会自动重新连接并重建所有的订阅者。它还提供了群集和故障转移支持。试试看吧。


12
“极其小心”?这是什么含糊的威胁?EasyNetQ是一个完全适当的建议。如果有人不同意,那就用下投票按钮表达不同意见。如果他没有声明自己的作者身份,这个建议可能不会受到第二次考虑。我建议你小心不要过于自大。 - G-Wiz
好的答案。它与https://www.rabbitmq.com/dotnet-api-guide.html相一致。 - Max Barraclough
EasyNetQ非常棒!但是有时候我会收到“请求的流水线禁止”这个错误。 - Allan Zeidler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接