Spring Boot Integration RabbitMQ Instance

What is a message?

Messages are a way of communicating between one or more entities and are ubiquitous.

Since the invention of computers, computers have sent messages in a variety of ways. Messages define how software, hardware, or applications communicate.Messages always have one sender and multiple recipients. Messages are synchronous and asynchronous, pub-sub and peer-to-peer, RPC and enterprise-based, Message Broker, ESB (Enterprise Service Bus), MOM
(Message Oriented Middleware) etc.

From these we can be sure that messages loosely couple distributed communication, meaning that it doesn't matter how the sender sends and what message is sent, and the recipient doesn't tell the sender when consuming the message.

Spring Boot RabbitMQ

Because protocols used by Microsoft, such as Sun/Oracle/IBM's JMS, and Microsoft's MSMQ, are all proprietary, we know that JMS only provides some interface API s, but if you try to mix technologies and programming languages to use JMS, this can be quite complex.The continuous innovation of technology has brought us a result that complex problems will arise and simple solutions will emerge.In the field of computer messaging, there is a special need to thank the JPMorgan team for inventing the AMQP (Advance Message Queuing Protocol).AMQP is an open standard application layer protocol designed for MOM (Message Oriented Middleware).In other words, if you use this protocol, you can use any technology or language.

Among the messaging systems that implement AMQP protocol, RabbitMQ is one of the most widely used. RabbitMQ is a typical representative of MQ products. The server side is written in Erlang language and supports a variety of clients, such as Python, Ruby,.NET, Java, JMS, C, PHP, ActionScript, XMPP, STOMP, etc. and supports AJAX.Used to store forwarded messages in a distributed system, it performs well in terms of ease of use, scalability, high availability, and so on.

This article mainly describes how to integrate RabbitMQ in SpringBoot and use RabbitMQ.

Install RabbitMQ

This example installs RabbitMQ on CentOS7. Search engines can find different installation methods for different systems.

1. Install the erlang language environment

  • Download Installation
wget http://www.erlang.org/download/otp_src_20.1.tar.gz//download Erlang package
tar -xzvf otp_src_20.1.tar.gz  //decompression
cd otp_src_20.1/  //Switch to Installation Path
./configure --prefix=/usr/local/erlang  //Production Installation Configuration
make && make install  //Compile Installation
  • Configuring environment variables
vi /etc/profile

Add the following at the bottom

#set erlang environment
ERL_HOME=/usr/local/erlang
PATH=$ERL_HOME/bin:$PATH
export ERL_HOME PATH

source /etc/profile  //Take effect

Test whether the installation was successful and enter the command erl in the console

erl 

If entering the shell of erlang proves that the installation was successful, exit.

Note: The following errors may be reported when executing the. /configure-prefix=/usr/local/erlang command:

configure: error: No curses library functions found
configure: error: /bin/sh '/home/jiayi/otp_src_20.1/erts/configure' failed for erts

You can try to execute the following command to solve the problem:

yum -y install ncurses-devel

2. Install RabbitMQ

  • Download Installation
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.0/rabbitmq-server-generic-unix-3.7.0.tar.xz //Download RabbitMQ installation package
xz -d rabbitmq-server-generic-unix-3.7.0.tar.xz
tar -xvf rabbitmq-server-generic-unix-3.7.0.tar

Folder rabbitmq-server-3.7.0 was unzipped and renamed rabbitmq for memory.

mv rabbitmq_server-3.7.0/ rabbitmq
  • Configuring rabbitmq environment variables
vi /etc/profile

Add the following at the bottom

#set rabbitmq environment
export PATH=$PATH:/data/rabbitmq/rabbitmq/sbin

source /etc/profile  //Take effect
  • Start Services
rabbitmq-server -detached //Start rabbitmq, -detached starts on behalf of the background daemon.

View the status if the following screenshot shows that the installation was successful:

rabbitmqctl status

Other related commands

Start service: rabbitmq-server-detached
View status: rabbitmqctl status
Shut down service: rabbitmqctl stop
List Roles: rabbitmqctl list_users

Configure Web Page Plugins

Create directory first, otherwise error may occur

mkdir /etc/rabbitmq

Then enable the plug-in

rabbitmq-plugins enable rabbitmq_management
  •  

Configure Firewall

Configure linux port 15672 Web page management 5672 AMQP port:

firewall-cmd --permanent --add-port=15672/tcp
firewall-cmd --permanent --add-port=5672/tcp
systemctl restart firewalld.service

Now you can see RabbitMQ's WEB administration page by typing server IP:15672 into your browser. Are you excited, but you don't have an account password? Don't worry.(

Configure access account passwords and permissions

The default web page is not allowed. You need to add a user to modify the permissions, and the code is as follows

rabbitmqctl add_user superrd superrd  //Add user, the last two parameters are user name and password, I use superrd.
rabbitmqctl set_permissions -p / superrd ".*" ".*" ".*"  //add permission
rabbitmqctl set_user_tags superrd administrator  //Modify user roles
  • 1
  • 2
  • 3

Then you can access it remotely and configure information such as user permissions directly.(

RabbitMQ/AMQP: Exchanges, Bindings and Queues

AMQP defines three very easy-to-understand concepts, Exchanges, Bindings, and Queues.

  • Exchanges: Delivery of messages to queue s is done through exchanges, where each exchange carries a message and routes to Queues.

  • Bindings: The routing of messages involves an algorithm related to the types of exchanges and some rules, that is, the routing of messages follows certain rules, which we call Bindings.

  • Queues: Queues is where Massage falls and waits to be received.

AMQP defines four exchange types, Direct, Fanout, Topic, and Headers.The following diagram shows the characteristics of different exchange types.(

Although AMQP defines different Exchange types, the main idea is to send a message containing a routing key to the exchange, which then distributes the message to the queue based on its native type.If no queue message is matched, it will be thrown into a black hole

default exchange will automatically bind to each queue that has been created.

direct exchange will bind to the specified queue through routing key, and you can see that this exchange type is a one-to-one binding.

topic exchange is similar to direct exchange, but the only difference is that you can add wildcards to routing key in its binding.

headers exchange is similar to topic exchange, but the only difference is that binding s are based on message headers, which is a very powerful exchange in which you can do everything and add any expression.

Fanout exchanges copy messages to all bound queues; such exchanges can be broadcast as messages.

This article describes how to integrate Spring Boot with RabbitMQ by using the default exchange type.

1. Building message consumers

Configure pom.xml as follows

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.springboot</groupId>
    <artifactId>rabbitereceiver</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>rabbitereceiver</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

The pom.xml contains spring-boot-starter-amqp starter pom, which contains all the spring-amqp and rabbitmq-client libraries needed to link to RabbitMQ middleware.

Create a new Spring Boot project, add the Consumer class, and write the following code.

package com.springboot.rabbitereceiver.rabbitmq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class Consumer {
    private static final Logger log = LoggerFactory.getLogger(Consumer.class);

    @RabbitListener(queues="${myqueue}")
    public void handler(String message){
        log.info("Consumer> " + message);
    }
}
  • @Component: This annotation instantiates a common pojo into the spring container;

  • @RabbitListener: This annotated method (which can also annotate a class) is a processor created for all received messages, meaning that he can link to the queue of RabbitMQ and create a listener and deliver the message to the method.This listener can do its best to convert messages to the appropriate type by using the correct message converter.

Write the following in application.properties.

myqueue=spring-boot
spring.rabbitmq.host=192.168.199.227
spring.rabbitmq.username=superrd
spring.rabbitmq.password=superrd
spring.rabbitmq.port=5672
spring.rabbitmq.dynamic=true

1. Build message producers

We are in Spring Boot uses JDBC Template to access data On the basis of the project built in this article, we transform the project into a producer of messages. Our requirement is to produce a message each time the page is refreshed.

First add an amqp dependency to the pom.xml.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

Create a new rabbitmq package and add the Producer class, adding the following code.

package com.springboot.rabbitmq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Producer {
    private static final Logger log = LoggerFactory.getLogger(Producer.class);

    @Autowired
    RabbitTemplate rabbitTemplate;

    public void sendTo(String routingkey,String message){
        log.info("Sending> ...");
        this.rabbitTemplate.convertAndSend(routingkey,message);
    }
}
  • @Autowired RabbitTemplate:RabbitTemplate is a simplified help class that synchronously accesses RabbitMQ send and receive.

  • sendTo(routingKey,message): This method has two parameters routing Key and message, in this case routing Key is the name of queue.This method uses the rabbitTemplate instance to call the convertAndSend method to accept routing keys and messages.The message is routed to exchange, which then routes the message to the correct queue.

The content written in the application.properties has always been the same as the consumer, and is not given here.

Add the following code to the JournalService:

@Value("${myqueue}")
String queue;

@Bean
Queue queue(){
        return new Queue(queue,false);
 }

@Autowired
Producer producer;

public void  sendMsg(String msg){
        producer.sendTo(queue,  msg+" at " + new Date());
 }
  • @Value : Value from application.properties;

  • @Bean Queue: Instantiates a bean of type Queue and creates a Queue using the queue string provided.The constructor of the Queue accepts the name of the queue and whether to persist it on service restart.

When the page loads, we invoke the sendMsg method from the service to produce a message.

@Controller
public class JournalController {
    @Autowired
    JournalService service;

    @RequestMapping("/")
    public String index(Model model){
        model.addAttribute("journal", service.findAll());

        service.sendMsg("Load index page");

        return "index";
    }
}

Before starting the project, add a queue through the RabbitMQ Web page management tool.(

Start two projects, Star the web page, and you can see the following in the message consumer's console.

2017-12-18 15:54:09.947  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:09 CST 2017
2017-12-18 15:54:10.648  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:10 CST 2017
2017-12-18 15:54:10.827  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:10 CST 2017
2017-12-18 15:54:11.007  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:11 CST 2017
2017-12-18 15:54:11.183  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:11 CST 2017
2017-12-18 15:54:11.336  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:11 CST 2017
2017-12-18 15:54:19.452  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:19 CST 2017
2017-12-18 15:54:19.614  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:19 CST 2017
2017-12-18 15:54:19.797  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Consumer> Load index page at Mon Dec 18 15:54:19 CST 2017
2017-12-18 15:54:19.987  INFO 4604 --- [cTaskExecutor-1] c.s.rabbitereceiver.rabbitmq.Consumer    : Con

Tags: RabbitMQ Spring Erlang Maven

Posted on Sat, 11 May 2019 17:14:05 -0700 by syth04