SpringBoot integrates Alibaba RocketMQ

Keywords: Programming Lombok Java Big Data Database

What is RocketMQ

Alibaba message queuing version RocketMQ not only provides asynchronous decoupling and peak clipping and valley filling capabilities for distributed application systems, but also has the features of massive message accumulation, high throughput, reliable retry and other features required by Internet applications, as well as charging products.

Application scenario

Peak shaving and valley filling

Large events such as seckill, red packet snatch, and enterprise success will bring high traffic pulses, or the system will be overloaded or even crash due to no corresponding protection, or the user experience will be affected due to too many requests fail due to too much restriction. RocketMQ version of message queuing can provide peak cutting and valley filling services to solve this problem.

Asynchronous decoupling

Transaction system is the core system of Taobao / tmall main station. The generation of each transaction order data will attract the attention of hundreds of downstream business systems, including logistics, shopping cart, integration, flow calculation and analysis, etc. the overall business system is huge and complex. RocketMQ version of message queue can realize asynchronous communication and application decoupling, and ensure the continuity of main station business.

Sequential transceiver

There are many application scenarios that need to ensure the order in daily detail, such as time priority principle in the securities trading process, order creation, payment, refund and other processes in the trading system, passenger boarding message processing in the flight, etc. Similar to the principle of First In First Out (FIFO for short), the sequential message provided by RocketMQ version of message queue guarantees the message FIFO.

Distributed transaction consistency

Transaction system, payment red packet and other scenarios need to ensure the final consistency of data. A large number of distributed transactions of RocketMQ version of message queue are introduced, which can not only realize the decoupling between systems, but also ensure the final data consistency.

Big data analysis

Data generates value in "flow". Traditional data analysis is mostly based on batch computing model, but it can't do real-time data analysis. Using Alibaba cloud message queuing RocketMQ and streaming computing engine, it is very convenient to realize real-time analysis of business data.

Distributed cache synchronization

Tmall double 11 promotes that a variety of commodities in each branch venue need real-time perception of price changes, a large number of concurrent access to the database results in a long response time of the venue page, the centralized cache restricts the access flow of commodity changes due to bandwidth bottleneck, builds a distributed cache through the message queue RocketMQ version, and notifies the changes of commodity data in real time.

1. Configure pom.xml

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

<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

<!--Ali RocketMQ-->
<dependency>
    <groupId>com.aliyun.openservices</groupId>
    <artifactId>ons-client</artifactId>
    <version>1.8.0.Final</version>
</dependency>

2. Configure application.properties

server.port=8888
#rocketmq configuration
#Authentication is created in alicloud server management console with AccessKeyId
rocketmq.accessKey=accessKey
#Authentication is created in the alicloud server management console with AccessKeySecret
rocketmq.secretKey=secretKey
#TCP long connection, set the TCP access domain name, enter the instance management page of the console, select the instance at the top of the page, and view it in the "get access point information" area of the instance information
rocketmq.namesrvAddr=http://MQ_INST_15namesrvAddr7I.cn-hangzhou.mq-internal.aliyuncs.com:8080
#mq theme, the topic you created in the console
rocketmq.topic=topic
#mq group name, the Group ID you created in the console
rocketmq.groupId=groupId

The above parameters can be found in the Alibaba console

3. Configuration class

package com.ifilldream.rocketmq_lean.mq;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.Properties;

/**
 * RocketMQ To configure
 * @author RickSun && iFillDream
 * @date 2020/01/10 15:58
 * @Copyright "Light dream to new "iFillDream" all WeChat public numbers.
 */
@Configuration
public class RocketMQConfig {

    @Value("${rocketmq.accessKey}")
    public String accessKey;
    public static String ACCESS_KEY;

    @Value("${rocketmq.secretKey}")
    public String secretKey;
    public static String SECRET_KEY;

    @Value("${rocketmq.namesrvAddr}")
    public String namesrvAddr;
    public static String NAMESRV_ADDR;

    @Value("${rocketmq.groupId}")
    public String groupId;
    public static String GROUP_ID;

    @Value("${rocketmq.topic}")
    public String topic;
    public static String TOPIC;

    /**
     * Configure RocketMq parameters
     * @return Properties
     */
    public Properties getProperties() {
        Properties properties = new Properties();
        //The GroupID you created in the console
        properties.put(PropertyKeyConst.GROUP_ID, groupId);
        // Authentication is created in alicloud server management console with AccessKeyId
        properties.setProperty(PropertyKeyConst.AccessKey, accessKey);
        // Authentication is created in the alicloud server management console with AccessKeySecret
        properties.setProperty(PropertyKeyConst.SecretKey, secretKey);
        //Delay Time
        properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
        // The unit of waiting time (in milliseconds) before retrying in case of order message consumption failure
        properties.put(PropertyKeyConst.SuspendTimeMillis, "100");
        // Maximum number of retries when message consumption fails
        properties.put(PropertyKeyConst.MaxReconsumeTimes, "20");
        // Set the TCP access domain name, enter the instance management page of the console, select an instance at the top of the page, and view it in the "get access point information" area of the instance information
        properties.put(PropertyKeyConst.NAMESRV_ADDR, namesrvAddr);
        return properties;
    }

    /**
     * Initializing static constants
     */
    @PostConstruct
    public void init(){
        ACCESS_KEY = this.accessKey;
        SECRET_KEY = this.secretKey;
        NAMESRV_ADDR = this.namesrvAddr;
        GROUP_ID = this.groupId;
        TOPIC = this.topic;
    }
}

4. RocketMQ tools

package com.ifilldream.rocketmq_lean.mq;
import com.aliyun.openservices.ons.api.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Properties;

/**
 * RocketMQ tool
 * @author RickSun && iFillDream
 * @date 2020/01/10 16:07
 * @Copyright "Light dream to new "iFillDream" all WeChat public numbers.
 */
@Component
@Slf4j
public class MQUtil {

    @Autowired
    private RocketMQConfig rocketMQConfig;

    /**
     * Send a normal message
     * @param content content
     * @param tag It can be understood as a label in Gmail, which can be used to re classify messages, so that the Consumer can specify filter conditions in the message queue
     */
    public void sendMessage(String content,String tag){
        Message message = new Message();
        message.setBody(content.getBytes());
        message.setTopic(RocketMQConfig.TOPIC);
        message.setTag(tag);
        this.sendCustomerMessage(message);
    }

    /**
     * Send scheduled task
     * @param content   content
     * @param tag   Label
     * @param delayTime Timing time
     */
    public void sendDelayMessage(String content,String tag,long delayTime){
        Message message = new Message();
        message.setBody(content.getBytes());
        message.setTopic(RocketMQConfig.TOPIC);
        message.setTag(tag);
        /**
         * Unit millisecond (ms)
         * Post after the specified time stamp (after the current time)
         * E.g. 2016-03-07 16:21:00 delivery
         * If it is set to a time before the current timestamp, the message will be delivered to the consumer immediately
         */
        message.setStartDeliverTime(System.currentTimeMillis()+delayTime);
        this.sendCustomerMessage(message);
    }

    /**
     * send message
     * @param message
     */
    private void sendCustomerMessage(Message message) {
        Properties properties=rocketMQConfig.getProperties();
        Producer producer = ONSFactory.createProducer(properties);
        //Before sending a message, you must call the start method to start Producer, just once
        producer.start();
        try {
            SendResult sendResult = producer.send(message);
            // Send message synchronously, as long as no exception is thrown, it is successful
            if (sendResult != null) {
                log.info("Message sent successfully: messageID: "+sendResult.getMessageId());
            }
        } catch (Exception e) {
            // Failed to send message, need to retry processing, can resend this message or persist this data for compensation processing
            e.printStackTrace();
        }
        //Destroy the Producer object before the app exits
        producer.shutdown();
    }
}

5, label

package com.ifilldream.rocketmq_lean.mq;

/**
 * RocketMQ Tag Business Tags
 * @author RickSun && iFillDream
 * @date 2020/01/10 16:32
 * @Copyright "Light dream to new "iFillDream" all WeChat public numbers.
 */
public class MqTag {
    /**
     * Create labels based on business experience
     */
    //Test 1
    public final static String ROCKETMQTEST1 = "ROCKETMQ_TEST1";
    //Test 2
    public final static String ROCKETMQTEST2 = "ROCKETMQ_TEST2";
}

6. Consumer

package com.ifilldream.rocketmq_lean.mq;
import com.aliyun.openservices.ons.api.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Properties;

/**
 * RocketMQ Consumer
 * @author RickSun && iFillDream
 * @date 2020/01/10 16:29
 * @Copyright "Light dream to new "iFillDream" all WeChat public numbers.
 */
@Component
@Slf4j
public class RocketMQConsumer {

    @Autowired
    private RocketMQConfig rocketMQConfig;

    /**
     * Subscribe to messages, process business
     */
    public void normalSubscribe() {
        Properties properties = rocketMQConfig.getProperties();
        Consumer consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe(RocketMQConfig.TOPIC, "", new MessageListener() {
            @Override
            public Action consume(Message message, ConsumeContext context) {
                try {
                    //Message content received
                    String msg = new String(message.getBody(), "UTF-8");
                    String tag = message.getTag();
                    switch (tag) {
                        case MqTag.ROCKETMQTEST1:
                            log.info("Receive message messageID: " + message.getMsgID() + " msg:" + msg);
                            //TODO do something
                            break;
                        case  MqTag.ROCKETMQTEST2:
                            log.info("Receive message messageID: " + message.getMsgID() + " msg:" + msg);
                            //TODO do something
                            break;
                    }
                    return Action.CommitMessage;
                } catch (Exception e) {
                    log.info("Consumption failure: messageID: " + message.getMsgID());
                    e.printStackTrace();
                    return Action.ReconsumeLater;
                }
            }
        });
        consumer.start();
    }
}

7. Consumer starts monitoring

package com.ifilldream.rocketmq_lean.mq;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * RocketMQ lsnrctl start
 * @author RickSun && iFillDream
 * @date 2020/01/10 16:07
 * @Copyright "Light dream to new "iFillDream" all WeChat public numbers.
 */
@Component
public class RocketConsumerListener implements CommandLineRunner {

    @Autowired
    private RocketMQConsumer rocketMQConsumer;

    @Override
    public void run(String... args) {
        System.out.println("========rocketMQ Consumer launch==========");
        rocketMQConsumer.normalSubscribe();
    }
}

8, interface

package com.ifilldream.rocketmq_lean.controller;
import com.ifilldream.rocketmq_lean.mq.MQUtil;
import com.ifilldream.rocketmq_lean.mq.MqTag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;

/**
 * @ClassName RocketController
 * @Author RickSun && iFillDream
 * @Date 2020/1/10 15:18
 * @Version 1.0
 */
@RestController
@RequestMapping("/ifilldream/rocketmq")
public class RocketController {

    @Resource
    private MQUtil mqUtil;

    @GetMapping("/test")
    public String test(String content) {
        return content;
    }

    @GetMapping("/test1")
    public String test1(String content) {
        mqUtil.sendMessage(content, MqTag.ROCKETMQTEST1);
        mqUtil.sendDelayMessage("test", MqTag.ROCKETMQTEST1, 1000L);
        return "success";
    }

    @GetMapping("/test2")
    public String test2(String content) {
        mqUtil.sendMessage(content, MqTag.ROCKETMQTEST2);
        mqUtil.sendDelayMessage("test", MqTag.ROCKETMQTEST2,3000L);
        return "success";
    }

}

After the code is completed, run the Jar package of the project on the Linux server, and enter: XX. XX. XX: 8888 / ifilldream / rocketmq / test1? Content = nihao in the browser to see the effect; xx.xx.xx.xx is the IP or domain name of the server. The operation effect is as follows: The above code can be used for personal test. For more details, please pay attention to the official documents of Alibaba https://help.aliyun.com/product/29530.html?spm=a2c4g.11186623.6.540.1a4b7e805ygc75

Unified starting platform for WeChat public number "light dream to new", search attention to the public number, the first time to read the latest content.

Posted by blackwinged on Thu, 16 Jan 2020 04:37:27 -0800