web front-end development software, form tag of HTML tag

Posted by fahhem on Sat, 15 Jan 2022 15:01:58 +0100

**MQ, also known as Message Queue, is a middleware for asynchronous communication** It can be understood as the post office. The sender delivers the message to the post office, and then the post office helps us send it to the specific message receiver (consumer). We don't need to care about the specific sending process and time, and it won't interfere with other things. Common MQS include kafka, activemq, zeromq, rabbitmq, etc. the comparison, advantages and disadvantages of each MQ can be determined by themselves

rabbitmq

RabbitMQ follows AMQP protocol and is developed by Erlang language for high concurrency. It is used for real-time message transmission with high reliability requirements and supports multi language clients. Support delay queue (this is a very useful function)

Basic concepts

**Broker: * * is simply a message queuing server entity
**Exchange: * * message switch, which specifies the rules by which messages are routed to which queue
**Queue: * * message queue carrier. Each message will be put into one or more queues
**Binding: * * binding, which is used to bind exchange and queue according to routing rules
**Routing Key: * * routing keyword. exchange delivers messages based on this keyword
**vhost: * * virtual host. Multiple vhosts can be set up in a broker to separate the permissions of different users
**Producer: * * message producer is the program that delivers messages
**Consumer: * * message consumer is the program that receives messages
**Channel: * * message channel. Multiple channels can be established in each connection of the client, and each channel represents a session task

Based on centos7 X for installation, refer to: http://blog.battcn.com/2017/08/20/linux/linux-centos7-ribbitmq/

Common application scenarios

  1. Email sending: after the user registers, the message is delivered to rabbitmq, and the message consumer sends the message asynchronously to improve the system response speed
  2. Traffic peak clipping: it is generally widely used in seckill activities. Seckill will cause the application to hang up due to excessive traffic. In order to solve this problem, the message queue is generally added to the front end of the application. It is used to control the number of active people and directly discard orders exceeding this certain threshold. Ease short-term high flow crushing applications.
  3. Order timeout: using rabbitmq's delay queue, you can easily realize the function of order timeout. For example, the user cancels the order 30 minutes after placing the order without paying
  4. There are more application scenarios not listed one by one

Import dependency

In POM Add the dependency of spring boot starter AMQP in XML

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.46</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Property configuration

Application rabbitmq is configured in the properties file. It is worth noting that the switch of manual ACK is configured here

spring.rabbitmq.username=battcn
spring.rabbitmq.password=battcn
spring.rabbitmq.host=192.168.0.133
spring.rabbitmq.port=5672
spring.rabbitmq.virtual-host=/
# Manual ACK does not enable the automatic ACK mode. The purpose is to prevent the loss of incorrectly processed messages after an error is reported. The default is none
spring.rabbitmq.listener.simple.acknowledge-mode=manual

Specific coding

Define queue

If the queue has been created manually or already exists in RabbitMQ, you can also omit the following code

package com.battcn.config;

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ to configure
 *
 * @author Levin
 * @since 2018/4/11 0011
 */
@Configuration
public class RabbitConfig {

    public static final String DEFAULT_BOOK_QUEUE = "dev.book.register.default.queue";
    public static final String MANUAL_BOOK_QUEUE = "dev.book.register.manual.queue";

    @Bean
    public Queue defaultBookQueue() {
        // The first is the name of QUEUE, and the second is whether the message needs persistence
        return new Queue(DEFAULT_BOOK_QUEUE, true);
    }

    @Bean
    public Queue manualBookQueue() {
        // The first is the name of QUEUE, and the second is whether the message needs persistence
        return new Queue(MANUAL_BOOK_QUEUE, true);
    }
}

Entity class

Create a Book class

public class Book implements java.io.Serializable {

    private static final long serialVersionUID = -2164058270260403154L;

    private String id;
    private String name;
	// Omit get set
}

controller

Write a Controller class for message sending

package com.battcn.controller;

import com.battcn.config.RabbitConfig;
import com.battcn.entity.Book;
import com.battcn.handler.BookHandler;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Levin
 * @since 2018/4/2 0002
 */
@RestController
@RequestMapping(value = "/books")
public class BookController {

    private final RabbitTemplate rabbitTemplate;

    @Autowired
    public BookController(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    /**
     * this.rabbitTemplate.convertAndSend(RabbitConfig.DEFAULT_BOOK_QUEUE, book); Corresponding to {@ link BookHandler#listenerAutoAck}
     * this.rabbitTemplate.convertAndSend(RabbitConfig.MANUAL_BOOK_QUEUE, book); Corresponding to {@ link bookhandler #listener manualack}
     */
    @GetMapping
    public void defaultMessage() {
        Book book = new Book();
        book.setId("1");
        book.setName("Let's learn together Spring Boot");
        this.rabbitTemplate.convertAndSend(RabbitConfig.DEFAULT_BOOK_QUEUE, book);
        this.rabbitTemplate.convertAndSend(RabbitConfig.MANUAL_BOOK_QUEUE, book);
    }
}

Message consumer

By default, {spring boot data AMQP} is an automatic ack mechanism, which means that MQ will automatically help us to ack after message consumption. In this way, there is a problem with dependency: if an error is reported, the message will not be lost and will be consumed in an infinite cycle. It is easy to run out of disk space. Although the number of consumption can be configured, this approach is also elegant. At present, it is recommended that we manually ACK and then transfer the consumption error message to other message queues for compensation

package com.battcn.handler;

import com.battcn.config.RabbitConfig;
import com.battcn.entity.Book;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * BOOK_QUEUE consumer
 *
 * @author Levin
 * @since 2018/4/11 0011
 */
@Component
public class BookHandler {

    private static final Logger log = LoggerFactory.getLogger(BookHandler.class);

    /**
     * <p>TODO This scheme is the default method of spring boot data AMQP and is not recommended. For details, it is recommended to use listener manual ack ()</p>
     * By default, if manual ACK is not configured, Spring Data AMQP will automatically help us to ACK after message consumption
     * Existing problems: if an error is reported, the message will not be lost, but it will be consumed in an infinite cycle. If the error log is enabled, it is easy to run out of disk space
     * Solution: manually ACK or try catch, and then transfer the error message in the catch to other series
     * spring.rabbitmq.listener.simple.acknowledge-mode=manual
     * <p>
     *
     * @param book Listening content
     */
    @RabbitListener(queues = {RabbitConfig.DEFAULT_BOOK_QUEUE})
    public void listenerAutoAck(Book book, Message message, Channel channel) {
        // If you manually ACK TODO, the message will be monitored and consumed, but the message still exists in the queue. If acknowledge mode is not configured, it will automatically ACK after consumption
        final long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            log.info("[listenerAutoAck Monitored messages] - [{}]", book.toString());
            // TODO notifies MQ that the message has been successfully consumed and can be ACK
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            try {
                // TODO processing failed, press MQ again
                channel.basicRecover();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    @RabbitListener(queues = {RabbitConfig.MANUAL_BOOK_QUEUE})
    public void listenerManualAck(Book book, Message message, Channel channel) {
        log.info("[listenerManualAck Monitored messages] - [{}]", book.toString());
        try {
            // TODO notifies MQ that the message has been successfully consumed and can be ACK
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            // If TODO reports an error, we can carry out fault-tolerant processing, such as transferring the current message to other queues
        }
    }
}

Main function

package com.battcn;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author Levin
 */
@SpringBootApplication
public class Chapter11Application {

    public static void main(String[] args) {
        SpringApplication.run(Chapter11Application.class, args);
    }
}

test

After completing the preparations, start Chapter11Application} access http://localhost:8080/books You will see the following, which means that everything is normal

2018-05-22 19:04:26.708  INFO 23752 --- [cTaskExecutor-1] com.battcn.handler.BookHandler           : [listenerAutoAck Monitored messages] - [com.battcn.entity.Book@77d8be18]
2018-05-22 19:04:26.709  INFO 23752 --- [cTaskExecutor-1] com.battcn.handler.BookHandler           : [listenerManualAck Monitored messages] - [com.battcn.entity.Book@8bb452]

summary

At present, many leaders have written tutorials on SpringBoot. If there are similarities, please forgive me. This tutorial is based on the latest spring boot starter parent: 2.0.2 Release, including the features of the new version, will be introduced together

last

This is the end of the article. If you think it's helpful to you, you can praise it. If you need a PDF full version of the front-end recruitment test questions, you can Click here to get it for free , including answer analysis.

Everyone has written a tutorial on spring boot. If there are any similarities, please forgive me. This tutorial is based on the latest spring boot starter parent: 2.0.2 Release, including the features of the new version, will be introduced together

last

This is the end of the article. If you think it's helpful to you, you can praise it. If you need a PDF full version of the front-end recruitment test questions, you can Click here to get it for free , including answer analysis.

[external chain picture transferring... (img-t0lIMULC-1627014938156)]

Topics: Front-end Interview Programmer