Ilya Grigorik recently wrote a nice summary about message handling with AMQP. Rany Keddo, the author of the Workling plugin, wrote another nice post about RabbitMQ with amqp. What is the most simple and basic example of using an AMQP message queue from Ruby? And what is an AMQP message queue anyway?
Message queues are useful to store a large number of items which can not be processed immediately and to achieve a loose coupling between application parts in general. There are two standard protocols for asynchronous message queues, AMQP and XMPP. AMQP is the lighter one which uses a binary format, while XMPP uses XML. AMQP means Advanced Message Queuing Protocol, it is an open standard application layer protocol for Message Oriented Middleware.
To use AMQP in Ruby, you can use either the carrot gem (a synchronous AMQP client without using EventMachine) or the amqp gem (a simple AMQP driver for Ruby using EventMachine). You can install them both at once with
$ sudo gem install amqp carrot
And you need to install a server implementing AMQP. RabbitMQ is an open source AMQP broker written in Erlang. To install the Erlang package and the RabbitMQ daemon under Ubuntu or Debian try
$ sudo apt-get install rabbitmq-server
Then you can start or stop the RabbitMQ daemon (the Linux counterpart of a service in Windows) with
$ sudo /etc/init.d/rabbitmq-server start $ sudo /etc/init.d/rabbitmq-server stop
Here is a simple example for a publish/subscribe message exchange process using an AMQP message queue. The information flow in the publish/subscribe pattern is similar to the client/server pattern, the difference is that the server is sending (=publishing) and the client is listening (=subscribing), instead of the client-server pattern where the server is listening and the client is sending. Run ruby client.rb in one console and ruby server.rb in another:
client.rb (subscriber)
require 'rubygems' require 'amqp' require 'mq' AMQP.start(:host => 'localhost' ) do q = MQ.new.queue('tasks') q.subscribe do |msg| puts msg end end
server.rb (publisher)
require 'rubygems' require 'amqp' require 'mq' AMQP.start(:host => 'localhost') do MQ.queue('tasks').publish("hello world") MQ.queue('tasks').publish("it is #{Time.now}") AMQP.stop { EM.stop } end
It is also possible to use EM.run instead of AMQP.start. It is necessary to call AMQP.stop, otherwise you will be stuck in an endless loop. Another possibility is using the carrot gem:
client.rb (subscriber)
require 'rubygems' require 'carrot' q = Carrot.queue('tasks', :durable => true) puts "count: #{q.message_count}" while msg = q.pop(:ack => true) puts msg q.ack end Carrot.stop end
server.rb (publisher)
require 'rubygems' require 'carrot' q = Carrot.queue('tasks') q.publish("hello world") q.publish("it is #{Time.now}")
Your post has been linked at http://www.DrinkRails.com
If you don’t need async RabbitMQ access, then you may want to take a look at Bunny gem.
This week I just started work on a daemon that is access a local RabbitMQ using Bunny. It’s a tad simpler than ampq/carrot and been rock-solid for about a week.
The carrot code doesn’t work as is.
There is a syntax error in client.rb (the carrot version).
That last “end” shouldn’t be there.
Also, the code in client.rb fails with:
/Library/Ruby/Gems/1.8/gems/carrot-0.8.1/lib/amqp/queue.rb:60:in `status’: undefined method `message_count’ for # (NoMethodError)
from /Library/Ruby/Gems/1.8/gems/carrot-0.8.1/lib/amqp/queue.rb:46:in `message_count’
from client.rb:6
ERROR: While executing gem … (Zlib::DataError)
incorrect header check
i was able to make the carrot example work with
1) making sure the queues in both files are :durable
q = Carrot.queue(‘tasks’, :durable => true)
2) removing the “end” after the Carrot.stop
When running client.rb or server.rb I get the following message:
————————————————————————————-
DEPRECATION WARNING!
Use of mq.rb is deprecated. Instead of
require “mq”
please use
require “amqp”
mq.rb will be REMOVED in AMQP gem version 1.0.
Why is it deprecated? Because it was a poor name choice all along. We better not
release 1.0 with it. Both mq.rb and MQ class step away from AMQP terminology and
make 8 out of 10 engineers think it has something to do with AMQP queues (in fact,
MQ should have been called Channel all along). No other AMQP client library we know
of invents its own terminology when it comes to AMQP entities, and amqp gem shouldn’t,
too.
Learn more at http://bit.ly/amqp-gem-080-migration, all documentation guides are at
http://bit.ly/amqp-gem-docs, AMQP Model Explained at http://bit.ly/amqp-model-explained.
We are also in #rabbitmq on irc.freenode.net.
Thank you for understanding. AMQP gem maintainers team.
————————————————————————————-