The implementation of delay message in ActiveMQ of SpringBoot

Keywords: Java Session Apache Lombok

I. installation of activeMQ

Please refer to the online tutorial for installation steps, which will not be introduced in this article

II. Modify the activeMQ configuration file

New configuration information of broker schedulerSupport="true"

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true" >

        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry topic=">" >
                    <!-- The constantPendingMessageLimitStrategy is used to prevent
                         slow topic consumers to block producers and affect other consumers
                         by limiting the number of messages that are retained
                         For more information, see:

                         http://activemq.apache.org/slow-consumer-handling.html

                    -->
                  <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                  </pendingMessageLimitStrategy>
                </policyEntry>
              </policyEntries>
            </policyMap>
        </destinationPolicy>

III. create spring boot project

  1. Configure ActiveMQ factory information. The trust package must be configured or an error will be reported
package com.example.demoactivemq.config;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.RedeliveryPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * @author shanks on 2019-11-12
 */
@Configuration
public class ActiveMqConfig {

    @Bean
    public ActiveMQConnectionFactory factory(@Value("${spring.activemq.broker-url}") String url){
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(url);
        // Set trust serialization package collection
        List<String> models = new ArrayList<>();
        models.add("com.example.demoactivemq.domain");
        factory.setTrustedPackages(models);

        return factory;
    }

}
  1. Message entity class
package com.example.demoactivemq.domain;

import lombok.Builder;
import lombok.Data;

import java.io.Serializable;

/**
 * @author shanks on 2019-11-12
 */

@Builder
@Data
public class MessageModel implements Serializable {
    private String titile;
    private String message;
}
  1. Producer
package com.example.demoactivemq.producer;


import lombok.extern.slf4j.Slf4j;
import org.apache.activemq.ScheduledMessage;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jms.JmsProperties;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.jms.*;
import java.io.Serializable;


/**
 * Message producer
 *
 * @author shanks
 */
@Service
@Slf4j
public class Producer {

    public static final Destination DEFAULT_QUEUE = new ActiveMQQueue("delay.queue");

    @Autowired
    private JmsMessagingTemplate template;

    /**
     * send message
     *
     * @param destination destination Is the queue sent to
     * @param message     message Is the message to be sent
     */
    public <T extends Serializable> void send(Destination destination, T message) {
        template.convertAndSend(destination, message);
    }

    /**
     * Delayed transmission
     *
     * @param destination Sent queue
     * @param data        Messages sent
     * @param time        delay time
     */
    public <T extends Serializable> void delaySend(Destination destination, T data, Long time) {
        Connection connection = null;
        Session session = null;
        MessageProducer producer = null;
        // Get connection factory
        ConnectionFactory connectionFactory = template.getConnectionFactory();
        try {
            // Get connection
            connection = connectionFactory.createConnection();
            connection.start();
            // Get session, true start transaction, false close transaction
            session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
            // Create a message queue
            producer = session.createProducer(destination);
            producer.setDeliveryMode(JmsProperties.DeliveryMode.PERSISTENT.getValue());
            ObjectMessage message = session.createObjectMessage(data);
            //Set delay time
            message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
            // send message
            producer.send(message);
            log.info("Send message:{}", data);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (producer != null) {
                    producer.close();
                }
                if (session != null) {
                    session.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
  1. Consumer
package com.example.demoactivemq.producer;


import com.example.demoactivemq.domain.MessageModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

/**
 * Consumer
 */
@Component
@Slf4j
public class Consumer {


    @JmsListener(destination = "delay.queue")
    public void receiveQueue(MessageModel message) {
        log.info("Receive message:{}", message);
    }
}
  1. application.yml
spring:
  activemq:
    broker-url: tcp://localhost:61616
  1. Test class
package com.example.demoactivemq;

import com.example.demoactivemq.domain.MessageModel;
import com.example.demoactivemq.producer.Producer;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest(classes = DemoActivemqApplication.class)
@RunWith(SpringRunner.class)
class DemoActivemqApplicationTests {

    /**
     * Message producer
     */
    @Autowired
    private Producer producer;

    /**
     * Timely message queuing test
     */
    @Test
    public void test() {
        MessageModel messageModel = MessageModel.builder()
                .message("Test message")
                .titile("News 000")
                .build();
        // send message
        producer.send(Producer.DEFAULT_QUEUE, messageModel);
    }

    /**
     * Delay message queue test
     */
    @Test
    public void test2() {
        for (int i = 0; i < 5; i++) {
            MessageModel messageModel = MessageModel.builder()
                    .titile("Delay execution by 10 seconds")
                    .message("Test message" + i)
                    .build();
            // Send delay message
            producer.delaySend(Producer.DEFAULT_QUEUE, messageModel, 10000L);
        }
        try {
            // Sleep for 100 seconds, etc. message execution
            Thread.currentThread().sleep(100000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

results of enforcement

2019-11-12 22:18:52.939 info 17263 -- [main] c.e.demoactivemq.producer.producer: send message: messagemodel (title = delay execution for 10 seconds, message = test message 0)
2019-11-12 22:18:52.953 info 17263 -- [main] c.e.demoactivemq.producer.producer: send message: messagemodel (title = delay execution for 10 seconds, message = test message 1)
2019-11-12 22:18:52.958 info 17263 -- [main] c.e.demoactivemq.producer.producer: send message: messagemodel (title = delay execution for 10 seconds, message = test message 2)
2019-11-12 22:18:52.964 info 17263 -- [main] c.e.demoactivemq.producer.producer: send message: messagemodel (title = delay execution for 10 seconds, message = test message 3)
2019-11-12 22:18:52.970 info 17263 -- [main] c.e.demoactivemq.producer.producer: send message: messagemodel (title = delay execution for 10 seconds, message = test message 4)
2019-11-12 22:19:03.012 info 17263 -- [enercontainer-1] c.e.demoactivemq.producer.consumer: received message: messagemodel (title = execution delayed by 10 seconds, message = test message 0)
2019-11-12 22:19:03.017 info 17263 -- [enercontainer-1] c.e.demoactivemq.producer.consumer: received message: messagemodel (title = execution delayed by 10 seconds, message = test message 1)
2019-11-12 22:19:03.019 info 17263 -- [enercontainer-1] c.e.demoactivemq.producer.consumer: received message: messagemodel (title = execution delayed by 10 seconds, message = test message 2)
2019-11-12 22:19:03.020 info 17263 -- [enercontainer-1] c.e.demoactivemq.producer.consumer: received message: messagemodel (title = execution delayed by 10 seconds, message = test message 3)
2019-11-12 22:19:03.021 info 17263 -- [enercontainer-1] c.e.demoactivemq.producer.consumer: received message: messagemodel (title = execution delayed by 10 seconds, message = test message 4)

The person who is better than you works harder than you, what qualification do you have not to fight!!!

Posted by Jamesm on Tue, 12 Nov 2019 07:09:10 -0800