(Quick Reference)

5 Publishing Messages - Reference Documentation

Authors: Bud Byrd

Version: 3.1.3

5 Publishing Messages

Publishing messages through the plugin is achieved by using the rabbitMessagePublisher bean. This Spring bean utilizes a closure-based configuration method to both send messages without waiting for a response, and sending rpc-style messages. There are many options available to the rabbitMessagePublisher which are documented in the reference, but this guide will only demonstrate basic usage.

In a multi-server setup, it is important to consider what server to send a message to. Like configuration and consumers, the connection property is used to route the message to the proper server connection.

5.1 Sending Messages

Sending a message means publishing a message to an exchange or queue and not waiting for a response (fire and forget). The only required parameters to the publisher are a queue or exchange to publish the message to, and the body of the message.

Send Example

import com.budjb.rabbitmq.publisher.RabbitMessagePublisher

class ExampleService { RabbitMessagePublisher rabbitMessagePublisher

def sendSomeMessage() { rabbitMessagePublisher.send { exchange = "some.exchange" routingKey = "some.routingKey" body = "hi!" } } }

RabbitMQ expects the body of a message to be a byte array. Message converters will also work when publishing messages, so if an object type other than byte is encountered, a suitable message converter will be found and run against the message body, if one exists.

5.2 RPC Messages

Publishing an RPC message is as easy as sending messages, except the returned message is returned from the function.

RPC Example

import com.budjb.rabbitmq.publisher.RabbitMessagePublisher

class ExampleService { RabbitMessagePublisher rabbitMessagePublisher

def sendSomeMessage() { def result = rabbitMessagePublisher.rpc { exchange = "some.exchange" routingKey = "some.routingKey" body = "hi!" timeout = 5000 } } }

The timeout option is especially important for RPC-style messages. The timeout property is the amount of time (in milliseconds) the client will wait for the server to respond. If the timeout is reached, a TimeoutException will be thrown. If the timeout is set to 0, the client will wait indefinitely for a response. The default value of the timeout, if not passed, is 5 seconds.

More options for the RabbitMessagePublisher can be found in the Quick Reference.

5.3 Bulk Publishing

By default, the publisher opens a new channel for each message it publishes. This is acceptable when sending individual messages, but when bulk publishing is required, it is much more efficient to open a single channel and use it for batches of messages.

As an example, during testing it took about 65 milliseconds to send one message. If 1000 messages are sent, the total time to publish is about 65 seconds! Using a single channel for the same operation takes about 1 millisecond per message, cutting the time down to 1 second for all 1000 messages.

These times are just an example based on testing, but they will differ based on network latency and server load.

While a channel may be manually created by authors using the rabbitContext, the publisher provides an easy way to send many messages with a single channel. See the example below.

rabbitMessagePublisher.withChannel { channel ->
    1000.times { i ->
        send {
            routingKey = "foobar"
            body = "Bulk message $i"
        }
    }
}

There is also a withChannel method that takes in a connection name for multi-server setups.

rabbitMessagePublisher.withChannel("connection1") { channel ->
    1000.times { i ->
        send {
            routingKey = "foobar"
            body = "Bulk message $i on connection1"
        }
    }
}

All of the send and rpc methods available with the publisher can be used with withChannel.

5.4 Publisher Confirms

The publisher allows authors to enable publisher confirms for a batch of messages using a similar mechanism as withChannel. These methods use RabbitMQ's waitForConfirms and waitForConfirmsOrDie methods. See RabbitMQ's documentation for more information about how publisher confirms work.

The reference details all of the various methods that the publisher contains to support confirms, but below are a couple of basic examples.

The withConfirms methods utilize the waitForConfirms methods from the RabbitMQ Java library. withConfirms will block until all messages sent in the provided closure have been acked or n'acked by the server. If a timeout is specified, it will only wait for the amount of time specified before throwing a TimeoutException.

rabbitMessagePublisher.withConfirms { channel ->
    send {
        routingKey = "foobar"
        body = "I am a test message"
    }

send { routingKey = "barbaz" body = "I am also a test message" } }

The withConfirmsOrDie methods utilize the waitForConfirmsOrDie methods from the RabbitMQ Java library. withConfirmsOrDie will block until all messages sent in the provided closure have been acked or n'acked by the server. The difference with this method is that if any n'ack is received, an exception is thrown. As with withConfirms, a timeout can be used.

rabbitMessagePublisher.withConfirmsOrDie { channel ->
    send {
        routingKey = "foobar"
        body = "I am a test message"
    }

send { routingKey = "barbaz" body = "I am also a test message" } }

There are versions of both of these types of methods that take a connection name and/or a timeout.