6
头图
As a commonly used middleware in development, message queues are mainly used to handle scenarios such as peak clipping, asynchrony, and decoupling. RabbitMQ is widely used because of its simple use, flexible configuration, and convenient management. In order to make it easy for Xiaobai to get started quickly, the class representative translated the original text of the official tutorial for your reference. The following is the first one: "Hello World"

1 "Hello World"

Introduction

RabbitMQ is a message broker: it receives and forwards messages. You can think of it as a post office. When you put the letter to be sent in the mailbox, you can be sure that a certain postman will eventually deliver your letter to the recipient. In this analogy, RabbitMQ is mailbox + post office + postman

The main difference between RabbitMQ and the post office is that it does not process paper letters. Instead, it receives, stores, and forwards binary data—messages.

In RabbitMQ and message delivery, the following terms are used:

  • Producing is sending. The program that sends the message is the producer:

生产(Producing)

  • The queue is the mailbox in RabbitMQ. Although messages flow from RabbitMQ to your application, messages can only be stored in queues. The queue is limited by the host's memory and hard disk size, and its essence is a huge message buffer. Producers can send messages to the queue, and consumers can receive messages from the queue. The queue can be represented by the following figure:

队列(Queue)

  • Consuming is to receive messages. The consumer is a program waiting to receive a message:

The producer, consumer, and message broker do not need to be on the same host. In fact, in most application scenarios, the three are on different machines. An application can be either a producer or a consumer.

"Hello World"

(Java code implementation)

In this part of the tutorial, we will write two Java applications: the producer is used to send a single message, and the consumer is used to receive the message and print the received message. We will introduce several Java APIs in detail to implement this simple function. This is the "Hello World" of messaging.

In the figure below, "P" is the producer, "C" is the consumer, and the red box in the middle is the queue-the message buffer provided by RabbitMQ for consumers.

Producer-queue-Consumer

Java library

RabbitMQ supports multiple protocols. This tutorial uses AMQP 0-9-1, which is an open source and general messaging protocol. RabbitMQ's client supports multiple programming languages. This article uses the Java client provided by RabbtiMQ.

Download the corresponding Java library and related dependencies ( SLF4J API and SLF4J Simple ). Copy the file to the working directory.

It should be noted that SLF4J Simple is only used for tutorial demonstration. For production environment, please use the full-featured logging library, such as: Logback

(The Java client of RabbitMQ is also provided in the Maven repository, groupId: com.rabbitmq, artifactId: amqp-client)

Now that you have a Java client and dependent libraries, you can write some code.

Sending

We named the message publisher (sender) class Send, and the message consumer (receiver) named Recv. The publisher will connect to RabbitMQ, send a message, and then exit.

In Send.java , the following classes need to be introduced:

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

Write class code to name the queue:

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

Then connect to the server

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

Connection class encapsulates the socket connection and handles protocol version negotiation and authentication for us. Here we are connected to the RabbitMQ node of this machine-because the connection address is written as localhost .

If you want to connect to other machine nodes, you only need to specify the host name or IP address.

Next, create channel , all the work of the API depends on channel complete. Since both Connection and channel implement java.io.Closeable , we can use the try-with-resource statement to prevent explicit write shutdown code.

To send a message, you need to declare a queue (queue) as the target; then send the message to this queue, all the code can be written in the try-with-resource 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 + "'");

Declaring a queue operation is idempotent-that is, it will only be created if the declared queue does not exist. The message content is an array of characters, so that arbitrary content can be encoded.

Click to view Send.java source file

Receiving

The above is the publisher. Our consumers want to listen to messages from RabbitMQ. Unlike the publisher sending a single message each time, the consumer will always run and listen for the message, and then print the monitored message.

接收(Receiving)

Recv.java references and Send as:

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

We will use the DeliverCallback interface to cache the messages sent to us by the server.

The configuration code is the same as that of the publisher: create connection and channel , and declare which queue (queue) needs to consume messages from. This should correspond to the publisher's queue.

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 run the producer before running the publisher, this is written to ensure that the corresponding queue exists when the message is consumed.

Why not use try-with-resource statement to automatically close channel and connection ? If you write in this way, it is equivalent to let the program continue to execute, close all resources and exit the application! And our purpose is to hope that the application will always be alive and continuously listen for messages asynchronously.

Next, we will tell the server to send the message in the queue. Since the server pushes messages to us asynchronously, we provide a callback in the form of an object to cache the message until the message is available. This is the role of the DeliverCallback

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 -> { });

Click to view Recv.java source file

Code integration (Putting it all together)

Just put the RabbitMQ java client code under the classpath, and you can compile these two files:

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

In order to run them, you need rabbitmq-client.jar and its dependencies. Run the consumer (receiver) in the terminal:

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

Then run the sender:

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

Under Windows, the item separator in the classpath uses a semicolon instead of a colon.

The consumer will print out the message published by the publisher obtained through RabbitMQ. The consumer program will continue to run, waiting to receive messages (using ctrl+c to stop), so you can open another terminal to run the sender.

List queue

You may want to know what queues RabbitMQ has, and how many messages are in each queue.

It can be viewed through the rabbitmqctl tool:

sudo rabbitmqctl list_queues

Omit sudo under Windows system:

rabbitmqctl list_queues

Next, we learn second part , to create a simple work queue.

hint

In order to shorten the command, you can set environment variables for these classpaths

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

Under 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

Recommended reading

Freemarker Tutorial (1)

downloaded attachment name is always garbled? You should read the RFC document!


The code word is not easy, welcome to like and share.
Search: [ Java class representative ], follow the official account, and get more Java dry goods in time.


Java课代表
640 声望1k 粉丝

JavaWeb一线开发,5年编程经验