RabbitMQ Java HelloWorld example

Posted by TTT on Fri, 18 Feb 2022 18:02:06 +0100

introduce

precondition

This tutorial assumes that RabbitMQ has install And run in Standard port (5672). If you use different hosts, ports, or credentials, you need to adjust the connection settings.

Where can I get help

If you have problems reading this tutorial, you can mailing list Or RabbitMQ community Slack contact us.

RabbitMQ is a message broker: it accepts and forwards messages. You can think of it as a post office: when you put the mail to be mailed into the mailbox, you can be sure that the postman will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a mailbox, a post office, and a postman.

The main difference between RabbitMQ and the post office is that it does not process paper, but accepts, stores, and forwards binary block messages.

RabbitMQ and general messaging use some jargon.

  • Production is nothing more than sending. The program that sends the message is the producer:

     

  • The queue is the name of the mailbox located in RabbitMQ. Although messages flow through RabbitMQ and your application, they can only be stored in queues. The queue is limited only by the memory and disk of the host. It is essentially a large message buffer. Many producers can send messages to a queue, and many consumers can try to receive data from a queue. This is how we represent queues:

  • Consumption and reception have similar meanings. A consumer is a program that primarily waits to receive a message:

     

Please note that producers, consumers and agents do not have to reside on the same host; In fact, they don't exist in most applications. Applications can also be both producers and consumers.

"Hello world"

(using Java client)

In this part of this tutorial, we will write two programs in Java; A producer who sends a single message and a consumer who receives and prints the message. We will ignore some details in the Java API and focus on this very simple thing just to get started. This is the "Hello World" of the message.

In the figure below, "P" is our producer and "C" is our consumer. The middle box is a queue -- a message buffer that RabbitMQ holds on behalf of the consumer.

Java client library

RabbitMQ uses a variety of protocols. This tutorial uses AMQP 0-9-1, which is an open and general messaging protocol. RabbitMQ yes Many different languages Client. We will use the Java client provided by RabbitMQ.

download Client Library And its dependencies( SLF4J API And SLF4J Simple ). Copy these files together with the tutorial Java files to your working directory.

Note that SLF4J Simple is sufficient for tutorials, but you should use it in production Logback Such a mature log library.

(RabbitMQ Java client is also in the central Maven repository, with groupId # com.rabbitmq and artifactId # AMQP client.)

Now that we have the Java client and its dependencies, we can write some code.

send out

 

We will call our message publisher (sender) Send and our message consumer (receiver) Recv. The publisher will connect to RabbitMQ, Send a message, and then exit.

In Send.java In, we need to import some classes:

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

Set the class and name the queue:

public class Send {
  private final static String QUEUE_NAME = "hello";
  public static void main(String[] argv) throws Exception {
      ...
  }
}

Then we can create a connection to the server:

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
     Channel channel = connection.createChannel()) {

}

Connection abstracts socket connection and handles protocol version negotiation and authentication for us. Here, we connect to the RabbitMQ node on the local machine - so it's localhost. If we want to connect to a node on another machine, we just need to specify its host name or IP address here.

Next, we create a Channel, which is where most of the API s that complete the task are located. Note that we can use the try with resources statement because both Connection and Channel implement Java io. Closeable. This way, we don't need to explicitly close them in the code.

To send, we must declare a queue for us to send; Then we can publish the message to the queue, all of which are in the try with resources statement:

channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello World!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");

Declare a queue idempotent - it is created only if it does not exist. The message content is an array of bytes, so you can encode anything you like there.

This is the whole send Java class.

Invalid sending!

If this is your first time using RabbitMQ and you don't see the "sent" message, you may be confused about what might be wrong. Perhaps the agent does not have enough free disk space at startup (it requires at least 200 MB of free space by default), so it rejects the message. Check the agent log file to confirm and reduce restrictions if necessary. to configure File document Will show you how to set up the disk_free_limit.

receive

This is our publisher. Our consumers listen to messages from RabbitMQ, so unlike publishers who publish a single message, we will let consumers continue to run to listen for messages and print them out.

 

Code (in) Recv.java (in) has almost the same import as Send:

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

We will use an additional DeliverCallback interface to buffer messages pushed to us by the server.

The settings are the same as those of the publisher; We open a connection and a channel and declare the queue we will consume. Note that this matches the queue to which the publication was sent.

public class Recv {

  private final static String QUEUE_NAME = "hello";

  public static void main(String[] argv) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

  }
}

Note that we also declare the queue here. Because we may start the consumer before the publisher, we need to ensure that the queue exists and then try to consume the message from it.

Why don't we use the try with resource statement to automatically close channels and connections? By doing so, we just need to keep the program running, close everything, and then exit! This can be awkward because we want the process to remain active when the consumer asynchronously listens for messages to arrive.

We will tell the server to deliver the message to us from the queue. Since it will push messages to us asynchronously, we provide a callback in the form of an object that will buffer messages until we are ready to use them. This is what the subclass DeliverCallback does.

DeliverCallback deliverCallback = (consumerTag, delivery) -> {
    String message = new String(delivery.getBody(), "UTF-8");
    System.out.println(" [x] Received '" + message + "'");
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });

This is the whole recv Java class.

Put them together

You can compile both using only the RabbitMQ java client on the classpath:

javac -cp amqp-client-5.7.1.jar Send.java Recv.java

To run them, you need rabbitmq client Jar and its dependencies on classpath. In the terminal, run the consumer (receiver):

java -cp .:amqp-client-5.7.1.jar:slf4j-api-1.7.26.jar:slf4j-simple-1.7.26.jar Recv

Then run the publisher (sender):

java -cp .:amqp-client-5.7.1.jar:slf4j-api-1.7.26.jar:slf4j-simple-1.7.26.jar Send

On Windows, use semicolons instead of colons to separate items in the classpath.

Consumers will print messages from publishers through RabbitMQ. The consumer will continue to run, waiting for the message (stop it with Ctrl-C), so try running the publisher from another terminal.

List queues

You may want to see which queues RabbitMQ has and how many messages are in them. You can do this using the rabbitmqctl tool (as a privileged user):

sudo rabbitmqctl list_queues

On Windows, omit sudo:

rabbitmqctl.bat list_queues

It's time to enter Part 2 And build a simple work queue.

hint

To save input, you can set environment variables for the classpath, such as

export CP=.:amqp-client-5.7.1.jar:slf4j-api-1.7.26.jar:slf4j-simple-1.7.26.jar
java -cp $CP Send

Or on Windows:

set CP=.;amqp-client-5.7.1.jar;slf4j-api-1.7.26.jar;slf4j-simple-1.7.26.jar
java -cp %CP% Send

Production [non] applicability Disclaimer

Remember that this and other tutorials are tutorials. They present new concepts one at a time and may deliberately oversimplify some things while ignoring others. For example, topics such as connection management, error handling, connection recovery, concurrency, and metric collection have been largely omitted for brevity. This simplified code should not be considered production ready.

Before using your application, please review the rest file. In particular, we recommend the following guidelines: Publisher confirmation and consumer confirmationProduction list and monitor.

Topics: Java RabbitMQ Distribution