SpringBoot集成RabbitMQ实现延迟队列

选择

延迟队列的实现有3种方法:

  • 队列设置TTL :不够灵活,每增加一个TTL时间,都要新增一条队列
  • 消息设置TTL :消息入队后,遵循先进先出,TTL长的仍然比TTL短的先消费
  • 基于插件实现: 消息通过自定义交换机后,不会立即分发到队列,而且存储到mnesia(分布式数据系统)表中,
    达到投递时间(TTL),就投递到目标队列

所以:选择基于插件实现延迟队列

安装

下载地址

下载:rabbit_delayed_message_exchange插件,解压到RabbitMQ/plugins目录

使用命令 rabbitmq-plugins enable rabbitmq_delayed_message_exchange 激活使用

流程图

image.png

实现步骤
声明配置
spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
声明队列,交换机,绑定关系
@Configuration
public class DelayQueueConfig {

    public static final String DELAYED_EXCHANGE_NAME = "delayed.exchange";
    public static final String DELAYED_QUEUE_NAME = "delayed.queue";
    public static final String DELAYED_ROUTING_KEY = "delayed.routingkey";

    //声明队列
    @Bean
    public Queue delayedQueue(){
        return new  Queue(DELAYED_QUEUE_NAME);
    }
    //声明一个延迟交换机
    @Bean("delayedExchange")
    public CustomExchange delayExchange(){
        //自定义交换机类型
        HashMap<String, Object> map = new HashMap<>();
        map.put("x-delayed-type","direct");
        /**
         * 1.交换机名称
         * 2.交换机类型
         * 3.是否需要持久化
         * 4.是否需要自动删除
         * 5.其他参数
         */
        return new CustomExchange(DELAYED_EXCHANGE_NAME,"x-delayed-message",true,false,map);
    }
    //绑定队列和延迟交换机
    @Bean
    public Binding bingQueueToExchange(@Qualifier("delayedQueue") Queue queue,
                                       @Qualifier("delayedExchange") CustomExchange customExchange){
        return BindingBuilder.bind(queue).to(customExchange).with(DELAYED_ROUTING_KEY).noargs();
    }
}
声明生产者
@Slf4j
@RequestMapping("ttl")
@RestController
public class Producer {

    public static final String DELAYED_EXCHANGE_NAME = "delayed.exchange";
    public static final String DELAYED_ROUTING_KEY = "delayed.routingkey";

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //基于插件实现的延迟队列
    @GetMapping("/sendDelayMsg/{msg}/{delayTime}")
    public void sendMag(@PathVariable String msg,@PathVariable Integer delayTime){
        rabbitTemplate.convertAndSend(DELAYED_EXCHANGE_NAME,DELAYED_ROUTING_KEY,msg, correlationDate ->{
            correlationDate.getMessageProperties().setDelay(delayTime);
            return correlationDate;
        });
        log.info("当前时间:{},延迟为:{},发送消息内容为:{}",new Date(),delayTime,msg);
    }
}
声明消费者
@Slf4j
@Component
public class Consumer {

    public static final String DELAYED_QUEUE_NAME = "delayed.queue";

    //基础插件实现的延迟队列消费者
    @RabbitListener(queues = DELAYED_QUEUE_NAME)
    public void receiveQueue(Message message){
        String msg = new String(message.getBody());
        log.info("当前时间:{},收到消息内容为:{}",new Date().toString(),msg);
    }
}
启动测试
  • 浏览器中依次请求:
http://localhost:8080/ttl/sendDelayMsg/你爱我,我爱你/20000
http://localhost:8080/ttl/sendDelayMsg/你爱我,我爱你,爱情甜蜜蜜/2000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值