Springboot+rabbitMq,用死信队列实现延时消息

pom文件依赖

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

死信队列配置

注意:过期时间如果设在配置里面,每次重新设置过期时间的时候都需要删掉上一个过期时间创建的队列

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

/**
 * rabbitMq 死信队列
 *
 * @Author hjx
 * @create 2021/8/31 17:04
 **/
@Configuration
public class RabbitMqDelayConfig {


    public final static String DELAY_QUEUE_PER_QUEUE_TTL_NAME = "delay_queue_per_queue_ttl_file_delete";

    public final static String DELAY_PROCESS_QUEUE_NAME = "delay_process_queue_file_delete";

    public final static String DELAY_EXCHANGE_NAME = "delay_exchange_file_delete";
    //1000*60*30 = 1,800,000 (30分钟)
    public final static int QUEUE_EXPIRATION = 10000;

    @Bean
    Queue delayQueuePerQueueTTL() {
        return QueueBuilder.durable(DELAY_QUEUE_PER_QUEUE_TTL_NAME)
                .withArgument("x-dead-letter-exchange", DELAY_EXCHANGE_NAME) // DLX
                .withArgument("x-dead-letter-routing-key", DELAY_PROCESS_QUEUE_NAME) // dead letter携带的routing key
        //        .withArgument("x-message-ttl", QUEUE_EXPIRATION) // 设置队列的过期时间
                .build();
    }

    @Bean
    Queue delayProcessQueue() {
        return QueueBuilder.durable(DELAY_PROCESS_QUEUE_NAME)
                .build();
    }

    @Bean
    DirectExchange delayExchange() {
        return new DirectExchange(DELAY_EXCHANGE_NAME);
    }

    @Bean
    Binding dlxBinding(Queue delayProcessQueue, DirectExchange delayExchange) {
        return BindingBuilder.bind(delayProcessQueue)
                .to(delayExchange)
                .with(DELAY_PROCESS_QUEUE_NAME);
    }
}

自定义过期时间,如上面代码,先注释掉设置过期时间的配置;然后自己写一个配置类

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;

/**
 * @Author hjx
 * @create 2021/9/1 10:02
 **/
public class ExpirationMessagePostProcessor implements MessagePostProcessor {

    //过期时间
    private final String ttl;

    public ExpirationMessagePostProcessor(String ttl){
        this.ttl = ttl;
    }

    @Override
    public Message postProcessMessage(Message message) throws AmqpException {
        message.getMessageProperties().setExpiration(ttl);
        return message;
    }
}

生产者

/**
 * rabbitMq  消息生产者
 *
 * @Author hjx
 * @create 2021/8/31 17:04
 **/
@Component
public class RabbitMqDelaySender {

    @Autowired
    private AmqpTemplate rabbitTemplate;

    /**
     * 
     *
     * @param msg
     * @param expiration 过期时间
     * */
    public void Send(String msg,String expiration){this.rabbitTemplate.convertAndSend(RabbitMqDelayConfig.DELAY_QUEUE_PER_QUEUE_TTL_NAME, (Object) msg
                , new ExpirationMessagePostProcessor(expiration));
    }

}

消费者

import com.gpdi.mobileportal.marketingassistant.rabbitmq.config.RabbitMqDelayConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * rabbitMq 消费者
 *
 * @Author hjx
 * @create 2021/8/31 14:48
 **/
@Component
@EnableRabbit
public class RabbitMqReceiver {

    @RabbitListener(queues = RabbitMqDelayConfig.DELAY_PROCESS_QUEUE_NAME)
    public void getDLMessage(String msg){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 模拟执行任务
        System.out.println("这是延迟队列消费:" + msg + ":" + sdf.format(new Date()));

    }

}

 

参考:https://blog.csdn.net/xiaoguangtouqiang/article/details/90734440

posted @ 2021-09-01 10:41  丶木木丶丶  阅读(422)  评论(0)    收藏  举报