5 Publishing Messages - Reference Documentation
Authors: Bud Byrd
Version: 3.1.3
5 Publishing Messages
Publishing messages through the plugin is achieved by using therabbitMessagePublisher
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.RabbitMessagePublisherclass ExampleService { RabbitMessagePublisher rabbitMessagePublisher def sendSomeMessage() { rabbitMessagePublisher.send { exchange = "some.exchange" routingKey = "some.routingKey" body = "hi!" } } }
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.RabbitMessagePublisherclass 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" } } }
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" } } }
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 aswithChannel
. 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" } }
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" } }