水平和垂直缩放RabbitMQ消费者?

时间:2013-12-10 23:06:12

标签: ruby rabbitmq scalability

如何使用AMQP gem在Ruby中扩展RabbitMQ使用者?

我阅读了文档,并提出了一些(貌似)可行的方法 在一个微不足道的例子中。这些示例水平缩放。新流程连接起来 到代理并接收消息的子集。从那里每个过程都可以 启动多个消费者线程。它使用低级别的消费者界面 在文档中描述。

以下是代码:

require 'amqp'

workers = ARGV[1] || 4

puts "Running #{workers} workers"

AMQP.start do |amqp|
  channel = AMQP::Channel.new

  channel.on_error do |conn, ex|
    raise ex.reply_text
  end

  exchange = channel.fanout 'scaling.test', durable: true, prefetch: 1
  queue = channel.queue("worker_queue", auto_delete: true).bind(exchange)

  workers.times do |i|
    consumer = AMQP::Consumer.new channel, queue, "consumer-#{i}", exclusive = false, manual_ack = false

    consumer.consume.on_delivery do |meta, payload|
      meta.ack
      puts "Consumer #{consumer.consumer_tag} in #{Process.pid} got #{payload}"
    end
  end

  trap('SIGTERM') do
    amqp.start { EM.stop }
  end
end

有一些我不确定的事情:

  1. 交换类型是否重要?文档说明了直接交换负载平衡 队列之间的消息。我使用直接和扇出交换测试了这个例子 功能相同。所以,如果我想支持垂直和水平缩放,那么 交换型物质?
  2. :prefetch选项应该是什么?我认为一个人会是最好的。
  3. 负载均衡如何具体工作?文档说明了加载 平衡发生在消费者之间而不是在队列之间。但是,当我跑两个 我可以看到进程一打印出来:“1,2,3,4”,然后进行两次打印输出 “5,6,7,8”。我以为它们会出现问题,或者渠道本身就是消费者? 根据输出而不是文档,这是有意义的。
  4. 从EventMachine的角度来看,这看起来是否正确?我需要做某种事吗? 线程池,以使同一进程中的多个使用者正常工作?

1 个答案:

答案 0 :(得分:1)

对于像RabbitMQ这样的经纪人,documentation实际上涵盖了大部分内容,但回答了你的问题:

  1. 对于工作人员队列,您最有可能想要直接交换,即将消息(作业)准确地路由到一个工作人员,而不是同时将多个工作人员路由到多个工作人员。但这可能会根据您的工作而改变。根据定义,扇出应该将相同的消息路由到多个消费者。

  2. 此次安装时,预取应为1。一般来说,这要求代理用1消息填充消费者的网络缓冲区,直到确认为止。另一种设置是您有1名消费者和n名工作人员,在这种情况下,您可以将预取设置为n。此外,值得注意的是,在这种设置中,您不应该在完成工作之后才开始工作。

  3. 负载均衡基本上是消费者之间的循环。这就是你顺序看到一切的原因。如果每项工作花费不同的时间,您将看到分布发生变化。

  4. 我希望有所帮助。我暂时没有对Ruby AMQP库做任何事情 - 我们重写了所有workers in Go