Add in some more explanation, tidy up some parts
This commit is contained in:
parent
4ef420ba59
commit
a5a491cfbc
@ -1,9 +1,23 @@
|
||||
# The basics
|
||||
## RabbitMQ
|
||||
|
||||
RabbitMQ is a message broker. In essence, it accepts messages from
|
||||
_producers_, and delivers them to _consumers_. In-between, it can
|
||||
route, buffer, and persist the messages according to rules you give
|
||||
it.
|
||||
|
||||
# "Hello World"
|
||||
|
||||
In this tutorial we'll install RabbitMQ, then write two programs in
|
||||
Java; one to to send a message, and one to receive messages. We'll
|
||||
leave out much of the detail, concentrating on a very simple thing
|
||||
just to get started. It's a "Hello World" of messaging.
|
||||
Java; a producer that sends a single message, and a consumer that
|
||||
receives messages. We'll gloss over some of the detail in the Java
|
||||
API, concentrating on this very simple thing just to get started.
|
||||
It's a "Hello World" of messaging.
|
||||
|
||||
In the diagram below, "P" is our producer and "C" is our consumer. The
|
||||
box in the middle is a queue -- a message buffer that RabbitMQ keeps
|
||||
on behalf of the consumer.
|
||||
|
||||
**TODO** diagram
|
||||
|
||||
## Installing the RabbitMQ server
|
||||
|
||||
@ -12,8 +26,8 @@ If you are using a debian-based system, you can just
|
||||
$ apt-get install rabbitmq-server
|
||||
|
||||
Otherwise, follow the [install
|
||||
instructions](http://www.rabbitmq.com/install.html) for the platform
|
||||
of your choice to get the RabbitMQ server running.
|
||||
instructions](http://www.rabbitmq.com/install.html) for your platform
|
||||
to get the RabbitMQ server running.
|
||||
|
||||
You can test that it's running by issuing
|
||||
|
||||
@ -32,19 +46,17 @@ which will either tell you about the running applications, e.g.,
|
||||
...done.
|
||||
|
||||
in which case all is well, or tell you there's no RabbitMQ server
|
||||
running and give you some diagnostic information
|
||||
running and give you some diagnostic information.
|
||||
|
||||
Status of node rabbit@example ...
|
||||
Error: unable to connect to node rabbit@example: nodedown
|
||||
diagnostics:
|
||||
- nodes and their ports on mbridgen: [{rabbitmqctl31625,44295}]
|
||||
- current node: rabbitmqctl31625@example
|
||||
- current node home dir: /home/mikeb
|
||||
- current node cookie hash: 1T3feTAK4mCpuDxI/xu9lQ==
|
||||
## The Java client library
|
||||
|
||||
## Getting the Java client library
|
||||
RabbitMQ speaks [AMQP](http://amqp.org/), which is an open,
|
||||
general-purpose protocol for messaging. There are a number of clients
|
||||
for AMQP in [many different
|
||||
languages](http://www.delicious.com/alexisrichardson/rabbitmq+client). We'll
|
||||
use the Java client provided by RabbitMQ.
|
||||
|
||||
Download the [Java client library
|
||||
Download the [client library
|
||||
package](http://www.rabbitmq.com/java-client.html), and check its
|
||||
signature as described. Unzip it into your working directory and grab
|
||||
the JAR files from the unzipped directory:
|
||||
@ -52,23 +64,28 @@ the JAR files from the unzipped directory:
|
||||
$ unzip rabbitmq-java-client-bin-*.zip
|
||||
$ cp rabbitmq-java-client-bin-*/*.jar ./
|
||||
|
||||
(The RabbitMQ Java client is also in the central Maven repository,
|
||||
with the groupId `com.rabbitmq` and the artifactId `amqp-client`.)
|
||||
|
||||
Now we have the Java client and its dependencies, we can write some
|
||||
code.
|
||||
|
||||
# Publishing a message
|
||||
# Sending
|
||||
|
||||
We'll call our message sender `send` and our message receiver
|
||||
`recv`. The sender will connect to RabbitMQ, send a single message,
|
||||
then exit.
|
||||
|
||||
In `send.java`, we need some classes imported:
|
||||
In
|
||||
[`send.java`](http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/send.java),
|
||||
we need some classes imported: (**TODO** line numbers)
|
||||
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.Connection;
|
||||
import com.rabbitmq.client.Channel;
|
||||
import java.io.IOException;
|
||||
|
||||
then we create a connection to the server (this uses the default):
|
||||
then we can create a connection to the server:
|
||||
|
||||
public class send {
|
||||
public static void main(String[] argv) {
|
||||
@ -87,30 +104,16 @@ to the queue:
|
||||
chan.queueDeclare("hello", false, false, false, null);
|
||||
chan.basicPublish("", "hello", null, "Hello World!".getBytes());
|
||||
|
||||
The message contents is a byte array; you can encode whatever you like
|
||||
there.
|
||||
Declaring a queue is idempotent; it will be created if it's doesn't
|
||||
exist already. The message contents is a byte array, so you can encode
|
||||
whatever you like there.
|
||||
|
||||
Lastly, we close the channel and the connection;
|
||||
|
||||
conn.close();
|
||||
|
||||
Since many of these method calls can throw an `IOException`, we wrap
|
||||
the whole thing in a `try...catch`. Here's the whole of the class again.
|
||||
|
||||
public class send {
|
||||
public static void main(String[] argv) {
|
||||
try {
|
||||
Connection conn = new ConnectionFactory().newConnection();
|
||||
Channel chan = conn.createChannel();
|
||||
chan.queueDeclare("hello", false, false, false, null);
|
||||
chan.basicPublish("", "hello", null, "Hello World!".getBytes());
|
||||
conn.close();
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
System.err.println("IOException while publishing");
|
||||
}
|
||||
}
|
||||
}
|
||||
the whole thing in a `try...catch`. [Here's the whole of the class](http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/send.java).
|
||||
|
||||
## Consuming messages
|
||||
|
||||
@ -118,7 +121,7 @@ That's it for our sender. Our receiver is pushed messages from
|
||||
RabbitMQ, so unlike the sender which publishes a single message, we'll
|
||||
keep it running to listen for messages and print them out.
|
||||
|
||||
The code (in `recv.java`) has almost the same imports as `send`:
|
||||
The code (in [`recv.java`](http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/recv.java)) has almost the same imports as `send`:
|
||||
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
import com.rabbitmq.client.Connection;
|
||||
@ -140,10 +143,10 @@ Note this matches up with the queue `send` publishes to.
|
||||
Channel chan = conn.createChannel();
|
||||
chan.queueDeclare("hello", false, false, false, null);
|
||||
|
||||
We're about to tell the server to deliver us the messages in the
|
||||
queue. Since it will push us messages, we provide a callback in the
|
||||
form of an object that will buffer the messages until we're ready to
|
||||
use them. That is what `QueueingConsumer` does.
|
||||
We're about to tell the server to deliver us the messages from the
|
||||
queue. Since it will push us messages asynchronously, we provide a
|
||||
callback in the form of an object that will buffer the messages until
|
||||
we're ready to use them. That is what `QueueingConsumer` does.
|
||||
|
||||
QueueingConsumer consumer = new QueueingConsumer(chan);
|
||||
chan.basicConsume("hello", true, consumer);
|
||||
@ -152,35 +155,13 @@ use them. That is what `QueueingConsumer` does.
|
||||
System.out.println(new String(delivery.getBody()));
|
||||
}
|
||||
|
||||
In the above, `QueueingConsumer.nextDelivery()` blocks until another
|
||||
message has been delivered from the server.
|
||||
`QueueingConsumer.nextDelivery()` blocks until another message has
|
||||
been delivered from the server.
|
||||
|
||||
The rest is just closing the `try...catch` -- here's the whole class:
|
||||
|
||||
public class recv {
|
||||
public static void main(String[] argv) {
|
||||
try {
|
||||
Connection conn = new ConnectionFactory().newConnection();
|
||||
Channel chan = conn.createChannel();
|
||||
chan.queueDeclare("hello", false, false, false, null);
|
||||
QueueingConsumer consumer = new QueueingConsumer(chan);
|
||||
chan.basicConsume("hello", true, consumer);
|
||||
while (true) {
|
||||
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
|
||||
System.out.println(new String(delivery.getBody()));
|
||||
}
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
System.err.println("IOException while consuming");
|
||||
}
|
||||
catch (InterruptedException ie) {
|
||||
System.err.println("InterruptedException while consuming");
|
||||
}
|
||||
}
|
||||
}
|
||||
The rest is just closing the `try...catch` -- [here's the whole class](http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/recv.java).
|
||||
|
||||
You can compile both of these with just the RabbitMQ java client on
|
||||
the class path:
|
||||
the classpath:
|
||||
|
||||
$ javac -cp rabbitmq-client.jar send.java recv.java
|
||||
|
||||
@ -194,6 +175,8 @@ and in another, run the sender:
|
||||
shell2$ java -cp .:commons-io-1.2.jar:commons-cli-1.1.jar:rabbitmq-client.jar send
|
||||
|
||||
The receiver will print the messages it gets from the sender via
|
||||
RabbitMQ.
|
||||
RabbitMQ. If you run `send` before starting `recv`, you'll
|
||||
notice that RabbitMQ holds onto the message until `recv` connects and
|
||||
consumes from the queue.
|
||||
|
||||
Hello World!
|
||||
|
Loading…
Reference in New Issue
Block a user