RabbitMQ 是否应该 一个 channel 对应 一个 queue?

看了一下公司以前的项目, 一个项目就创建了一个 connection 和一个 channel , 一个 channel 承担了好几个 queue 的发布和消费. 
但是项目也还算稳定. 现在有新的项目要写, 我觉得这应该不好吧...
好像看到过有人说过

1 connection per app, 1 channel per thread, 1 consumer per channel.

( 由于我用的是 node , 不存在 per thread , 不过也好理解~ )
由于不知道这个说法是出自何处, 文档找了一下也没找到. 而且也好奇需要发布到多个 queue 的时候, 是否需要创建多个 channel 呢, 所以想知道大家都是怎么做的...

目前我的想法是, 一个 consumer 创建一个 channel, 但是纠结是所有的 queue 共用一个 channel 来发布消息, 还是为每个 queue 创建一个独立的 channel. 希望有人能指点一下. 😄

回答:

Consumer 确实最好是一个 Channel 一个 Queue,但这不是硬性要求;Producer 则没这个限制。

主要原因是你得明白 Channel 起了什么作用,它实质上是屏蔽了 Connection 的细节,让开发者不用去管 TCP 层面上的事儿,同时基于 NIO 可以使得 Connection 的 TCP 能够被复用,减少了 TCP 连接建立的开销。

(题外话,所有 Channel 共用一个 Connection 并不适用全部情况,有些场景下反而会降低性能。所以你说 1 Connection per App 并不是绝对的。)

至于 1 Channel per Thread,是因为 Channel 本身不是线程安全的,这个很好理解,不多展开。

而 1 Consumer per Channel,是因为如果一个 Consumer 在一个 Channel 中正在监听某一个 Queue的消息,那么这个 Consumer 是不能在这个 Channel 中同时去处理另一个 Queue 的,出于消费速度的考虑所以需要开辟多个 Channel,如果你本身没那么大消息吞吐量,也可以共用一个 Channel;而 Producer 是不存在这个问题的。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Linux 环境下,你可以使用 Python 的 `pika` 库来接收 RabbitMQ 的消息,并使用多线程来处理消息并发送结果。为了实现多线程间的同步,你可以使用 `threading.Event` 来进行线程间的通信和同步。以下是一个示例代码: ```python import subprocess import threading import pika # 创建一个事件对象用于线程间同步 event = threading.Event() # 定义外部程序调用函数 def call_external_program(thread_id, message): # 调用外部程序并获取结果 result = subprocess.check_output(['external_program', 'arg1', 'arg2', message]) # 获取 RabbitMQ 连接 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 发送消息到 RabbitMQ channel.basic_publish(exchange='', routing_key='result_queue', body=result) # 关闭 RabbitMQ 连接 connection.close() # 定义消息处理函数 def process_message(ch, method, properties, body): # 获取消息内容和线程ID message = body.decode() thread_id = int(properties.headers.get('thread_id', 0)) # 创建线程并启动外部程序调用 thread = threading.Thread(target=call_external_program, args=(thread_id, message)) thread.start() # 创建 RabbitMQ 连接 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() # 声明队列和交换机 channel.queue_declare(queue='message_queue') channel.queue_declare(queue='result_queue') # 设置消息处理回调函数 channel.basic_consume(queue='message_queue', on_message_callback=process_message, auto_ack=True) # 开启多个线程来处理消息 for i in range(10): # 设置线程ID到消息属性中 properties = pika.BasicProperties(headers={'thread_id': i}) # 发送同步信号 event.set() # 阻塞等待消息处理 channel.start_consuming() # 清除同步信号 event.clear() # 关闭 RabbitMQ 连接 connection.close() ``` 在这个示例中,我们使用一个事件对象 `event` 来进行线程间的同步。每个线程在调用外部程序之前都会等待事件的触发信号,一旦收到信号,就会开始处理消息并调用外部程序。当一个线程完成处理后,会通过 RabbitMQ 发送结果,并继续等待下一个触发信号。 请注意,你需要将 `external_program` 替换为你要调用的实际外部程序的名称,并根据实际情况进行参数的设置。同时,你也需要将 `message_queue` 和 `result_queue` 替换为你实际使用的 RabbitMQ 队列名称。 这个示例代码只是一个基本的框架,你可以根据自己的需求进行进一步的定制和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值