使用AMQP,Rabbit和Ruby刷新队列

时间:2010-04-15 01:49:15

标签: ruby rabbitmq amqp

我正在使用Ruby开发一个系统,它将利用RabbitMQ将消息发送到队列,因为它可以正常工作。我正在使用:

我在这个gem上看到的大多数例子都在EM.add_periodic_timer块中进行了发布调用。这不适用于我怀疑绝大多数用例,当然也不适用于我的用例。我需要在完成一些工作时发布消息,因此在add_periodic_timer块中放置发布语句是不够的。

所以,我正在试图找出如何将一些消息发布到队列,然后“刷新”它,以便我发布的任何消息然后传递给我的订阅者。

为了让您了解我的意思,请考虑以下发布商代码:

#!/usr/bin/ruby

require 'rubygems'
require 'mq'

MESSAGES = ["hello","goodbye","test"]

AMQP.start do

  queue = MQ.queue('testq')
  messages_published = 0

  while (messages_published < 50)

    if (rand() < 0.4)
      message = MESSAGES[rand(MESSAGES.size)]
      puts "#{Time.now.to_s}: Publishing: #{message}"
      queue.publish(message)
      messages_published += 1
    end

    sleep(0.1)

  end

  AMQP.stop do
    EM.stop
  end

end

因此,这段代码只是循环,在循环的每次迭代中以40%的概率发布消息,然后休眠0.1秒。它会在发布50条消息之前执行此操作,然后停止AMQP。当然,这只是一个概念证明。

现在,我的订户代码:

#!/usr/bin/ruby

require 'rubygems'
require 'mq'

AMQP.start do

  queue = MQ.queue('testq') 
  queue.subscribe do |header, msg|
    puts "#{Time.now.to_s}: Received #{msg}"
  end

end

因此,我们只订阅队列,对于收到的每条消息,我们将其打印出来。

很好,除了订阅者只在发布者调用AMQP.stop时收到所有50条消息。

以下是我的发布商的输出。为简洁起见,它在中间被截断:

$ ruby publisher.rb 
2010-04-14 21:45:42 -0400: Publishing: test
2010-04-14 21:45:42 -0400: Publishing: hello
2010-04-14 21:45:42 -0400: Publishing: test
2010-04-14 21:45:43 -0400: Publishing: test
2010-04-14 21:45:44 -0400: Publishing: test
2010-04-14 21:45:44 -0400: Publishing: goodbye
2010-04-14 21:45:45 -0400: Publishing: goodbye
2010-04-14 21:45:45 -0400: Publishing: test
2010-04-14 21:45:45 -0400: Publishing: test
.
.
.
2010-04-14 21:45:55 -0400: Publishing: test
2010-04-14 21:45:55 -0400: Publishing: test
2010-04-14 21:45:55 -0400: Publishing: test
2010-04-14 21:45:55 -0400: Publishing: goodbye

接下来,我订阅者的输出:

$ ruby consumer.rb
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received hello
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received goodbye
2010-04-14 21:45:56 -0400: Received goodbye
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received test
.
.
.
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received test
2010-04-14 21:45:56 -0400: Received goodbye

如果您在输出中记下时间戳,则订阅者只有在发布者停止AMQP并退出后才会收到所有消息。

因此,作为AMQP新手,我如何才能立即发送消息?我尝试将AMQP.start和AMQP.stop放在发布者的while循环体中,但之后只传递第一条消息 - 虽然奇怪的是,如果我打开日志记录,服务器并没有报告错误消息邮件会被发送到队列,但订阅者永远不会收到。

建议将不胜感激。谢谢你的阅读。

1 个答案:

答案 0 :(得分:2)

如果您想了解有关此问题的信息,请参阅http://groups.google.com/group/ruby-amqp/browse_thread/thread/311965bcf9697ece

我通过在发布商代码中添加了一个额外的帖子来解决问题:

!/usr/bin/ruby

require 'rubygems'
require 'mq'

MESSAGES = ["hello","goodbye","test"]

AMQP.start do

  Thread.new do
      queue = MQ.queue('testq')
      messages_published = 0

      while (messages_published < 50)

        if (rand() < 0.4)
          message = MESSAGES[rand(MESSAGES.size)]
          puts "#{Time.now.to_s}: Publishing: #{message}"
          queue.publish(message)
          messages_published += 1
        end

        sleep(0.1)

      end

      AMQP.stop do
        EM.stop
      end

  end

end