SpringBoot2.0 combat | Chapter XIX: integration of the delay queue RabbitMQ

related information

What is the delay queue

Messages in the queue after waiting for a specified time, consumers will be able to consume.

Scenarios

  • Mall system, after half an hour under a single non-payment, the order is automatically canceled

Method to realize

RabbitMQ itself does not directly support the queuing delay, but by the survival time and the dead letter queue control message, can simulate the effect of a delay queue.

RabbitMQ survival time control message in two ways:

  • Setting queue attributes (x-message-ttl), all the messages in the queue have the same expiration time
  • Set message properties (expiration), have separate expiration time

On the dead letter queue can refer https://gitee.com/gongm_24/spring-boot-tutorial/tree/master/chapter18

aims

Integration Spring boot provided spring-boot-starter-amqpto achieve delayed queue

Steps

Add dependent

The introduction of Spring Boot Starter parent project

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
</parent>

Add spring-boot-starter-amqpdependence

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

After adding the following overall dependence

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

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <scope>provided</scope>
    </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>

Coding (transmitter)

Configuration

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: admin
    password: admin
Defining the Queue

Define a test queue TestDeadQueue, and configure the dead letter queue for the queue,
the method is configured in a statement queue when adding parameters x-dead-letter-exchangeand x-dead-letter-routing-key,
in fact, when the consumer fails, the message is sent using the exchange and routing to the designated queue

@Configuration
public class DeadConfig {

    @Bean
    public Queue testDelayQueue() {
        Map<String, Object> params = new HashMap<>();
        params.put("x-dead-letter-exchange", "DeadExchange");
        params.put("x-dead-letter-routing-key", "DeadRouting");
        // 如果设置,则队列中所有消息的过期时间都是 5 秒,如果希望在每个消息中进行单独设置,则不能设置
        params.put("x-message-ttl", 5000);
        return new Queue("TestDelayQueue",true, false, false, params);
    }

    @Bean
    DirectExchange testDelayExchange() {
        return new DirectExchange("TestDelayExchange");
    }

    @Bean
    Binding bindingTestDelayQueue() {
        return BindingBuilder.bind(testDelayQueue()).to(testDelayExchange()).with("TestDelayRouting");
    }

    @Bean
    public Queue deadQueue() {
        return new Queue("DeadQueue",true);
    }

    @Bean
    DirectExchange deadExchange() {
        return new DirectExchange("DeadExchange");
    }

    @Bean
    Binding bindingDeadQueue() {
        return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("DeadRouting");
    }

}
Send test
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = SenderApplication.class)
public class MqTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    // 队列设置了过期时间
    @Test
    public void testDelayQueue() throws Exception {
        String msgId = String.valueOf(UUID.randomUUID());
        String sendTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String,Object> map = new HashMap<>(4);
        map.put("msgId", msgId);
        map.put("msgData", "test delay queue");
        map.put("sendTime", sendTime);
        rabbitTemplate.convertAndSend("TestDelayExchange", "TestDelayRouting", map);
    }

    // 对消息设置过期时间,队列不用设置过期时间
    @Test
    public void testDelayQueueWithMessage() throws Exception {
        String msgId = String.valueOf(UUID.randomUUID());
        String sendTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String,Object> map = new HashMap<>(4);
        map.put("msgId", msgId);
        map.put("msgData", "test dead letter queue");
        map.put("sendTime", sendTime);
        rabbitTemplate.convertAndSend("TestDelayExchange", "TestDelayRouting", map, msg -> {
            msg.getMessageProperties().setExpiration("5000");
            return msg;
        });
    }

}

Source Address

Source chapter: https://gitee.com/gongm_24/spring-boot-tutorial.git

Conclusion

To sum up the life cycle of delayed messages:

Created with Raphaël 2.2.0 客户端发送消息 业务队列 延迟队列 等待消息过期 死信队列 消费消息 yes
发布了153 篇原创文章 · 获赞 22 · 访问量 10万+

Guess you like

Origin blog.csdn.net/gongm24/article/details/103915040