Tag Archives: howto

RabbitMQ: Create a Cluster On a Single Machine

Sometimes it’s useful to be able to play around with a simple RabbitMQ cluster on a single machine. After trying to follow the instructions in the RabbitMQ Clustering Guide and running into a couple of issues, I ended up doing the following to get a working two node cluster up and running on my laptop.

The machine used was a laptop running Ubuntu 12.04.1 LTS (32-bit), RabbitMQ 3.0.1 and Erlang R14B04. These are the steps I took using the Terminal –

  1. To run commands as root enter –

    sudo -i

  2. Make sure that you don’t have a /etc/rabbitmq/rabbitmq.config file because it caused errors for me by applying the settings from the file to both nodes that I started irrespective of command line arguments. I renamed my rabbitmq.config file to rabbitmq.config.bak.
  3. Start the first RabbitMQ instance if it is not already running. In my case it is the default instance named ‘rabbit‘ –

    invoke-rc.d rabbitmq-server start

    Output –

    * Starting message broker rabbitmq-server
  4. Start a second RabbitMQ instance called ‘hare‘ on port 5673 as a background task. I have the Management plugin installed so also set the port for that –

    RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=hare rabbitmq-server &

    Output –

    Status of node 'hare@mymachine' ...

    Start up information was displayed but my prompt did not return, so I just pressed Ctrl-C to get the prompt back.

  5. The hare instance should be running –

    rabbitmqctl -n hare status

    Output –

    Status of node 'hare@mymachine' ...
         [{rabbitmq_management,"RabbitMQ Management Console","3.0.1"},
  6. Stop hare RabbitMQ application but leave Erlang node running –

    rabbitmqctl -n hare stop_app

    Output –

    Stopping node 'hare@mymachine' ...
  7. Reset hare

    rabbitmqctl -n hare reset

    Output –

    Resetting node 'hare@mymachine' ...
  8. Join hare to cluster –

    rabbitmqctl -n hare join_cluster rabbit@`hostname -s`

    Output –

    Clustering node 'hare@mymachine' with 'rabbit@mymachine' ...
  9. Restart the hare RabbitMQ application

    rabbitmqctl -n hare start_app

    Output –

    Starting node 'hare@mymachine' ...
    ** Found 0 name clashes in code paths
  10. Check the status of the cluster –

    rabbitmqctl cluster_status

    Output –

    Cluster status of node 'rabbit@mymachine' ...

That’s it! Now you can play with your shiny new cluster. Take a look at the RabbitMQ Clustering Guide for further information.

Bunny Howto: Subscribe to a queue

Bunny provides a simple way for a consumer to subscribe to queues. Here is an example –

require 'bunny'

my_client = Bunny.new
my_q = my_client.queue('my_queue')

ret = my_q.subscribe(:timeout => 5) { |msg| puts msg }
my_q.unsubscribe if ret == :timed_out

The Queue#subscribe method takes an optional timeout value and a mandatory code block.

The :timeout argument specifies how many seconds to wait for the next message to arrive on the queue before breaking out of the subscribe loop.

If a message arrives on the queue before the timeout period has elapsed, the message is processed and the timeout is reset to wait for the next message. If you do not provide a :timeout argument then a default timeout value of zero is used. This means that the subscribe will continue to process any received messages indefinitely until the process is halted by Ctrl-C for example.

The Queue#unsubscribe method cancels the consumer and tells the server to stop sending messages to that consumer. This does not affect messages that have already been delivered.

Both the Queue#subscribe and Queue#unsubscribe methods can take an optional :consumer_tag argument to identify the consumer. The server will generate a value for this if it is not passed explicitly.

The Queue#subscribe method also takes another two optional parameters –

  1. :ack => true or false – If set to true (default value is false), this argument tells the server that you will explicitly acknowledge receipt of messages (in Bunny this is done with the Queue#ack method).
  2. :header => true or false – If set to true (default value is false), when a message is received a hash containing :header, :payload and :delivery_details is passed to the code block. Otherwise, only the payload, which contains the message itself, is passed to the code block.

I am aware that there are problems with the timeout functionality in the Ruby 1.8.6 version of timeout.rb, however, I believe that most, if not all of these are solved in Ruby v1.9.1 and beyond. If the timeout option proves problematic for you under Ruby 1.8.6, let me know and I will explore alternative implementations.

To date I have not received any information one way or the other. Either people are using it and it has worked so far; people have had problems with it and have not told me about them; or no-one is using the Bunny subscribe functionality.

Above all, I hope that you enjoy using Bunny.