c# - RabbitMQ channel 创建指南

标签 c# messaging rabbitmq

我正在编写一个简单的类,我的应用程序将使用它来使用 RabbitMQ 发送和接收消息。 我已经阅读了尽可能多的有关 RabbitMQ 的操作方法、博客文章、白皮书和类似内容。 大多数示例都将连接和 channel 包装在 using block 中,并反驳说您应该将它们实现为单例。 具体来说,关于 channel ,我看到评论说您不应该有多个线程同时使用单个 channel 。

我正在用 C# 编写我的库。它是一个在第一次实例化时具有静态连接的单例。

我考虑过对 channel 做同样的事情,但我打算使用相同的库来允许发布/订阅多个交换/队列。发布和订阅都可以通过多个线程完成。

最后我的问题是: 我应该如何实现 channel 创建? 每条消息? 每个消费者是否都有一个独特的私有(private) channel ,发布者是否同步访问单个唯一 channel ? 你明白我的意思了。 请记住,我打算使用一台服务器,其中有几十个消费者/发布者,仅此而已。

最佳答案

编辑 (2016-1-26): channel 不是线程安全的。有关该内容的文档已在 April 之间更改。和 May 2015.新文本:

Channel instances must not be shared between threads. Applications should prefer using a Channel per thread instead of sharing the same Channel across multiple threads. While some operations on channels are safe to invoke concurrently, some are not and will result in incorrect frame interleaving on the wire. Sharing channels between threads will also interfere with * Publisher Confirms.

从您的问题来看,您似乎没有预定义的固定数量的线程,这些线程主要用于发布/订阅 RabbitMQ(在这种情况下,您可能会考虑创建一个 channel 作为线程初始化的一部分,或者使用ThreadLocal<IModel>)。

如果并发 RabbitMQ 操作很少或者消息大小总是很小,您可能只需放置 lock(channel) 就可以了。围绕所有 RabbitMQ 发布/订阅操作。如果您需要使用任意线程以交错方式传输多个请求(这就是 channel 的用途),您可能需要创建一个 channel 池,例如一个ConcurrentQueue<IModel>您可以在其中将未使用的 channel 入队并在需要时将其出队。 channel 创建的开销非常低,并且从性能测试中我感觉 channel 创建的过程不涉及任何网络io,即它客户端第一次使用时,RabbitMQ 服务器似乎会自动创建一个 channel 。 编辑:谢谢 Pang, There is no need to open a channel per operation and doing so would be very inefficient, since opening a channel is a network roundtrip.

<小时/>

OLD(2016 年 1 月 26 日之前):Java 和 .net 实现的现在大部分已过时的细节:

回复: channel 和多线程,由于其对实现的依赖,这有点令人困惑。

Java 实现:Channels are thread safe :

Channel instances are safe for use by multiple threads.

But :

confirms are not handled properly when a Channel is shared between multiple threads

.net 实现:Channels are not thread safe :

If more than one thread needs to access a particular IModel instances, the application should enforce mutual exclusion itself.

Symptoms of incorrect serialisation of IModel operations include, but are not limited to,

• invalid frame sequences being sent on the wire

• NotSupportedExceptions being thrown ...

因此,除了 Robin 的有用答案(无论线程是否安全都适用)之外,在 .net 实现中,您不能只共享 channel

关于c# - RabbitMQ channel 创建指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5681118/

相关文章:

android - 如何使用 smack API 4.1.0 android 发送一对一消息

c - 订阅与发布者相同的主题时发布失败?

c# - 循环触发一次通知

c# - 将 outerXml 转换为 OpenXmlElement

c# - 设计帮助——多态事件处理

python - 使用Kombu ConsumerMixin,如何声明多个绑定(bind)?

.net - 在发布方的 SimpleInjector for MassTransit 中建立队列

django - 使用 Django 在 Docker 上设置 RabbitMQ

c# - 如何在泛型类中访问 T 类型的静态属性?

c# - WCF TCP比HTTP快多少