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
|
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
|
Java; a producer that sends a single message, and a consumer that
|
||||||
leave out much of the detail, concentrating on a very simple thing
|
receives messages. We'll gloss over some of the detail in the Java
|
||||||
just to get started. It's a "Hello World" of messaging.
|
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
|
## Installing the RabbitMQ server
|
||||||
|
|
||||||
@ -12,8 +26,8 @@ If you are using a debian-based system, you can just
|
|||||||
$ apt-get install rabbitmq-server
|
$ apt-get install rabbitmq-server
|
||||||
|
|
||||||
Otherwise, follow the [install
|
Otherwise, follow the [install
|
||||||
instructions](http://www.rabbitmq.com/install.html) for the platform
|
instructions](http://www.rabbitmq.com/install.html) for your platform
|
||||||
of your choice to get the RabbitMQ server running.
|
to get the RabbitMQ server running.
|
||||||
|
|
||||||
You can test that it's running by issuing
|
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.
|
...done.
|
||||||
|
|
||||||
in which case all is well, or tell you there's no RabbitMQ server
|
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 ...
|
## The Java client library
|
||||||
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==
|
|
||||||
|
|
||||||
## 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
|
package](http://www.rabbitmq.com/java-client.html), and check its
|
||||||
signature as described. Unzip it into your working directory and grab
|
signature as described. Unzip it into your working directory and grab
|
||||||
the JAR files from the unzipped directory:
|
the JAR files from the unzipped directory:
|
||||||
@ -52,23 +64,28 @@ the JAR files from the unzipped directory:
|
|||||||
$ unzip rabbitmq-java-client-bin-*.zip
|
$ unzip rabbitmq-java-client-bin-*.zip
|
||||||
$ cp rabbitmq-java-client-bin-*/*.jar ./
|
$ 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
|
Now we have the Java client and its dependencies, we can write some
|
||||||
code.
|
code.
|
||||||
|
|
||||||
# Publishing a message
|
# Sending
|
||||||
|
|
||||||
We'll call our message sender `send` and our message receiver
|
We'll call our message sender `send` and our message receiver
|
||||||
`recv`. The sender will connect to RabbitMQ, send a single message,
|
`recv`. The sender will connect to RabbitMQ, send a single message,
|
||||||
then exit.
|
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.ConnectionFactory;
|
||||||
import com.rabbitmq.client.Connection;
|
import com.rabbitmq.client.Connection;
|
||||||
import com.rabbitmq.client.Channel;
|
import com.rabbitmq.client.Channel;
|
||||||
import java.io.IOException;
|
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 class send {
|
||||||
public static void main(String[] argv) {
|
public static void main(String[] argv) {
|
||||||
@ -87,30 +104,16 @@ to the queue:
|
|||||||
chan.queueDeclare("hello", false, false, false, null);
|
chan.queueDeclare("hello", false, false, false, null);
|
||||||
chan.basicPublish("", "hello", null, "Hello World!".getBytes());
|
chan.basicPublish("", "hello", null, "Hello World!".getBytes());
|
||||||
|
|
||||||
The message contents is a byte array; you can encode whatever you like
|
Declaring a queue is idempotent; it will be created if it's doesn't
|
||||||
there.
|
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;
|
Lastly, we close the channel and the connection;
|
||||||
|
|
||||||
conn.close();
|
conn.close();
|
||||||
|
|
||||||
Since many of these method calls can throw an `IOException`, we wrap
|
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.
|
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).
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
## Consuming messages
|
## 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
|
RabbitMQ, so unlike the sender which publishes a single message, we'll
|
||||||
keep it running to listen for messages and print them out.
|
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.ConnectionFactory;
|
||||||
import com.rabbitmq.client.Connection;
|
import com.rabbitmq.client.Connection;
|
||||||
@ -140,10 +143,10 @@ Note this matches up with the queue `send` publishes to.
|
|||||||
Channel chan = conn.createChannel();
|
Channel chan = conn.createChannel();
|
||||||
chan.queueDeclare("hello", false, false, false, null);
|
chan.queueDeclare("hello", false, false, false, null);
|
||||||
|
|
||||||
We're about to tell the server to deliver us the messages in the
|
We're about to tell the server to deliver us the messages from the
|
||||||
queue. Since it will push us messages, we provide a callback in the
|
queue. Since it will push us messages asynchronously, we provide a
|
||||||
form of an object that will buffer the messages until we're ready to
|
callback in the form of an object that will buffer the messages until
|
||||||
use them. That is what `QueueingConsumer` does.
|
we're ready to use them. That is what `QueueingConsumer` does.
|
||||||
|
|
||||||
QueueingConsumer consumer = new QueueingConsumer(chan);
|
QueueingConsumer consumer = new QueueingConsumer(chan);
|
||||||
chan.basicConsume("hello", true, consumer);
|
chan.basicConsume("hello", true, consumer);
|
||||||
@ -152,35 +155,13 @@ use them. That is what `QueueingConsumer` does.
|
|||||||
System.out.println(new String(delivery.getBody()));
|
System.out.println(new String(delivery.getBody()));
|
||||||
}
|
}
|
||||||
|
|
||||||
In the above, `QueueingConsumer.nextDelivery()` blocks until another
|
`QueueingConsumer.nextDelivery()` blocks until another message has
|
||||||
message has been delivered from the server.
|
been delivered from the server.
|
||||||
|
|
||||||
The rest is just closing the `try...catch` -- here's the whole class:
|
The rest is just closing the `try...catch` -- [here's the whole class](http://github.com/rabbitmq/rabbitmq-tutorials/blob/master/java/recv.java).
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
You can compile both of these with just the RabbitMQ java client on
|
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
|
$ 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
|
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
|
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!
|
Hello World!
|
||||||
|
Loading…
Reference in New Issue
Block a user