springboot集成rabbitmq死信队列实现延时处理

1.增加pom依赖

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

2.编写配置类



@Configuration
public class RabbitMQConfiguration {

    //队列名称
    public final static String orderQueue = "order_queue";

    //交换机名称
    public final static String orderExchange = "order_exchange";

    // routingKey队列路由键
    public final static String routingKeyOrder = "routing_key_order";

    //死信消息队列名称
    public final static String dealQueueOrder = "deal_queue_order";

    //死信交换机名称
    public final static String dealExchangeOrder = "deal_exchange_order";

    //死信 routingKey
    public final static String deadRoutingKeyOrder = "dead_routing_key_order";

    //死信队列 交换机标识符
    public static final String DEAD_LETTER_QUEUE_KEY = "x-dead-letter-exchange";

    //死信队列交换机绑定键标识符
    public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";

    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Bean
    public Queue orderQueue() {
        // 将普通队列绑定到死信队列交换机上
        Map<String, Object> args = new HashMap<>(2);
        //args.put("x-message-ttl", 5 * 1000);//直接设置 Queue 延迟时间 但如果直接给队列设置过期时间,这种做法不是很灵活
        //这里采用发送消息动态设置延迟时间,这样我们可以灵活控制
        args.put(DEAD_LETTER_QUEUE_KEY, dealExchangeOrder);
        args.put(DEAD_LETTER_ROUTING_KEY, deadRoutingKeyOrder);
        return new Queue(RabbitMQConfiguration.orderQueue, true, false, false, args);
    }

    //声明一个direct类型的交换机
    @Bean
    DirectExchange orderExchange() {
        return new DirectExchange(RabbitMQConfiguration.orderExchange);
    }

    //绑定Queue队列到交换机,并且指定routingKey
    @Bean
    Binding bindingDirectExchangeDemo5() {
        return BindingBuilder.bind(orderQueue()).to(orderExchange()).with(routingKeyOrder);
    }

    //创建配置死信队列
    @Bean
    public Queue deadQueueOrder() {
        Queue queue = new Queue(dealQueueOrder, true);
        return queue;
    }

    //创建死信交换机
    @Bean
    public DirectExchange deadExchangeOrder() {
        return new DirectExchange(dealExchangeOrder);
    }

    //死信队列与死信交换机绑定
    @Bean
    public Binding bindingDeadExchange() {
        return BindingBuilder.bind(deadQueueOrder()).to(deadExchangeOrder()).with(deadRoutingKeyOrder);
    }


}

3.编写监听器



@Component
public class MqFailureListener {

    @Autowired
    private RatingBasicInfoService basicInfoService;

    @RabbitListener(
            queues = RabbitMQConfiguration.dealQueueOrder
    )
    public void process(Integer id, Message message, @Headers Map<String, Object> headers, Channel channel) throws IOException {
        System.out.println("消息:用户id--------" + id);
        RatingBasicInfo ratingBasicInfo = basicInfoService.getById(id);
        String payPhoto = ratingBasicInfo.getPayPhoto();
        if (StringUtils.isEmpty(payPhoto)) {
            System.out.println("用户:" + ratingBasicInfo.getName() + ";未按时上传缴费截图");
            //delivery tag可以从消息头里边get出来
            Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
            //手动应答,消费者成功消费完消息之后通知mq,从队列移除消息,需要配置文件指明。第二个参数为是否批量处理
            channel.basicAck(deliveryTag, false);


            //移出队列,false只确保一个消息被消费并一处队列
            //channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }


    }


}

4.测试接口


@RestController
@RequestMapping("/test")
@Api(tags = "mq测试")
public class TestController {

    @Autowired
    private AmqpTemplate rabbitTemplate;

    @Autowired
    private RatingBasicInfoService basicInfoService;

    @GetMapping("/submit")
    @ApiOperation("提交信息")
    public ResponseEntity submit() {
        RatingBasicInfo ratingBasicInfo = new RatingBasicInfo();
        ratingBasicInfo.setName("xx");
        ratingBasicInfo.setOpenId("123");
        basicInfoService.save(ratingBasicInfo);
        System.out.println("创建成功......");
        // 放入死信队列
        //Rabbit延时队列,处理订单自动取消
        this.rabbitTemplate.convertAndSend(
                RabbitMQConfiguration.orderExchange,
                RabbitMQConfiguration.routingKeyOrder,
                ratingBasicInfo.getId(), message -> {
                    message.getMessageProperties().setExpiration(1000 * 30 + "");
                    return message;
                });
        System.out.println("发送消息......");
        return ResultUtil.success();
    }

}

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我心向阳cd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值