This is the 17th day of my participation in Gwen Challenge

MQ?

MQ (Message Quene) : Translated as Message queue. Through the typical producer and consumer model, producers continuously produce messages to the Message queue, and consumers continuously fetch messages from the queue. Because message production and consumption are asynchronous, and only care about message sending and receiving, no intrusion of business logic, easy to achieve decoupling between systems. Messaging middleware uses efficient and reliable messaging mechanisms to communicate platform-independent data and integrate distributed systems based on data communication.

Main purpose: Communication between threads and processes.

RabbitMQ

You’ll notice a very “crazy” statement. RabbitMQ is the most widely Deployed Open source message broker.

Indeed, the most popular one on the market is RabbitMQ.

RabbitMQ is a message broker: it accepts and forwards messages. You can think about it as a post office: when you put the mail that you want posting in a post box, you can be sure that Mr. or Ms. Mailperson will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a post box, a post office and a postman.

The major difference between RabbitMQ and the post office is that it doesn’t deal with paper, instead it accepts, stores and forwards binary blobs of data ‒ messages.

RabbitMQ is a message broker (also called middleware) : it receives and forwards messages. Think of it like a post office: When you drop your mail in a mailbox, you can be sure that Mr. Or Mrs. Messenger will eventually deliver it to your intended recipient. In this analogy RabbitMQ is a post office box, a post office and a postman.

Here’s the difference: RabbitMQ won’t process the contents for you (the official quote paper is for readers to understand), it will receive, store and forward them.

Install the RabbitMQ

I recommend starting a virtual machine and using Docker to install RabbitMQ, not Windows.

docker pull rabbitmq:management
docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management
Copy the code

Start and stop

docker start rabbitmq
docker stop rabbitmq 
Copy the code

Why are there two ports here

15672: WEB port. After RabbitMQ is enabled, use IP +15672 to access the port.

5672: Communication port (such as JAVA connection must use this port)

Access: your IP :15672, if you are local, localhost:15672, if you do not know the IP on the virtual machine (Linux), enter the command ifconfig to check

The default administrator password is guest

JAVA (Hello World)

In this part of the tutorial we’ll write two programs in Java; a producer that sends a single message, and a consumer that receives messages and prints them out. 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.

We will write two programs in Java

A producer sends a single message, and a consumer receives the message and prints it out. The official documentation says it will gloss over some of the details of the JavaAPI and focus on this very simple thing to get started. This is a “Hello World” message. But I’m a man of details, so I’ll handle it better than official details.

In the figure above, “P” is our producer and “C” is our consumer. The middle box is the queue -RabbitMQ represents the message buffer reserved by the consumer.

Design producer

We will create a new Maven project

Introduction of depend on

<dependencies>
    <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>5.9.0</version>
    </dependency>
</dependencies>
Copy the code

Create a producer class, name-> Producer, and note that factory. SetHost is the IP address of your installation

package com.xn2001;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/ * * *@authorHappy heart lake *@date2020/5/31 0:26 * * /
public class producer {

    // Name the queue
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) throws IOException, TimeoutException {
        // Create a factory to the server
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.123.128");
        // Create a connection
        Connection connection = factory.newConnection();
        // Create a channel, which is where most apis are used to get work done.
        Channel channel = connection.createChannel();
        // Declare (create) a queue
        channel.queueDeclare(QUEUE_NAME, false.false.false.null);
        String message = "Happy Heart lake is so handsome.";
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        System.out.println(" [x] Sent '" + message + "'"); channel.close(); connection.close(); }}Copy the code

Run the program and you can see that the message queue has been sent.

The 1 represents a message that has not been received by the consumer. Let’s go ahead and say hello,

Design consumer

Create a new class, name-> Consumer

package com.xn2001;

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

/ * * *@authorHappy heart lake *@date2020/5/31 0:51 * * /
public class consumer{
    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");
        // Since it will push our messages asynchronously, here we provide callbacks in the form of objects that will buffer messages until we use them.
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("[quality] Received '" + message + "'");
        };
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { }); }}Copy the code

Here’s a quote from the official

Why don’t we use a try-with-resource statement to automatically close the channel and the connection? By doing so we would simply make the program move on, close everything, and exit! This would be awkward because we want the process to stay alive while the consumer is listening asynchronously for messages to arrive.

Why don’t we try to close the channel and the connection here? If we do that, the program will run once and then pass over, and can’t be active, so how do we receive the message?

In other words, we must keep channels and connections active so that we can always listen for messages.

Let’s start Consumer and get the message.

We will encapsulate a utility class, RabbitMQUtil

package com.xn2001.util;

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

/ * * *@authorHappy heart lake *@date2020/5/31 13:01 * * /
public class RabbitMQUtil {

    private static ConnectionFactory connectionFactory;

    static {
        connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.111.129");
    }

    // Define methods to connect objects
    public static Connection getConnection(a) {
        try {
            return connectionFactory.newConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // Define a method to close channels and connections
    public static void closeChannelAndConnection(Channel channel, Connection connection) {
        try {
            if(channel ! =null) {
                channel.close();
            }
            if(connection ! =null) { connection.close(); }}catch(Exception e) { e.printStackTrace(); }}}Copy the code

Let me rewrite producers and consumers

package com.xn2001;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.xn2001.util.RabbitMQUtil;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/ * * *@authorHappy heart lake *@date2020/5/31 0:26 * * /
public class producer {

    // Name the queue
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] args) throws IOException {
        // Create a factory to the server
        //ConnectionFactory factory = new ConnectionFactory();
        / / factory. SetHost (" 192.168.111.129 ");

        // Create a connection
        //Connection connection = factory.newConnection();
        // Create a channel, which is where most apis are used to get work done.
        Connection connection = RabbitMQUtil.getConnection();
        Channel channel = connection.createChannel();
        // Declare (create) a queue
        channel.queueDeclare(QUEUE_NAME, false.false.false.null);
        String message = "Happy Heart lake is so handsome.";
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        System.out.println("[quality] Sent '" + message + "'"); RabbitMQUtil.closeChannelAndConnection(channel,connection); }}Copy the code
package com.xn2001;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import com.xn2001.util.RabbitMQUtil;

/ * * *@authorHappy heart lake *@date2020/5/31 0:51 * * /
public class comsumr {

    private final static String QUEUE_NAME = "hello";
    public static void main(String[] argv) throws Exception {
        //ConnectionFactory factory = new ConnectionFactory();
        / / factory. SetHost (" 192.168.111.129 ");
        //Connection connection = factory.newConnection();
        Connection connection = RabbitMQUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME, false.false.false.null);
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

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

explain

package com.xn2001;

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/ * * *@authorHappy heart lake *@date2020/6/1 15:52 * * /
public class Test {
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        / / set the IP
        factory.setHost("192.168.111.111");
        // If your port is not the default 5672, you need to set it.
        factory.setPort(5672);
        // If the user is not using guest, please look down
        // Set which VM to connect to
        factory.setVirtualHost("/ems");
        // Set the user name and password for accessing the VM
        factory.setUsername("ems");
        factory.setPassword("123456");
        // Get the connection object
        Connection connection = factory.newConnection();
        // Create a channel connection
        Channel channel = connection.createChannel();
        /** * channel bind message queue *@paramQueue Specifies the name of the message queue, automatically created if it does not exist@paramDurable Queue Whether the queue is durable. The queue still exists when rabbitMQ is restarted@paramExclusive Specifies whether to exclusively use a queue. Only one queue is allowed. This parameter is set to false *@paramAutoDelete automatically deletes the message queue * when the message is consumed@param arguments
         */
        channel.queueDeclare("hello".false.false.false.null);
        /** * Release message *@paramExchange Switch name *@paramRoutingKey Message queue name *@paramProps message additional Settings, such as message need persistence, can be set to MessageProperties. PERSISTENT_TEXT_PLAIN *@paramBody Message content */
        channel.basicPublish(""."hello".null."hello rabbitmq".getBytes());

        / / closechannel.close(); connection.close(); }}Copy the code

Note: ABOVE I have only shown the usual Settings for producers; consumers are almost the same in theory.

Also, you need to be concerned that the producer and consumer message queue parameters must be the same in order to make a match.