Spring Cloud Stream RabbitMQ死信队列学习笔记(三)

大家好,我叫大鸡腿,大家可以关注下我,会持续更新技术文章还有人生感悟,感谢~

在这里插入图片描述

死信产生

  在mq里头死信的产生:

  1. 消费失败重试到最大次数
  2. 消息ttl(也就是生存时间达到最大值)

这些都会进入到RabbitMQ DLX Exchange交换器进行重新扔到对应的队列进行消费

如何处理消费过程的异常

  因为如果消费过程出现问题,mq会认为消费失败,重新消费。有时也可能你消费超时了是吧。所以有了去除重复消费的观点。
那么如何在消费消息时处理异常?
伪代码

@StreamListener(Processor.INPUT)

    public void input(Message<String> message) throws Exception {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(System.currentTimeMillis()) + " " + "一般监听收到:" + message.getPayload());
        try{
            a();
        }catch (Exception e){
            System.out.println("记录异常");
        }


    }
    @Transactional(rollbackFor = Exception.class)
    public void a(){
        throw new RuntimeException();
    }

死信处理

rabbit:
        bindings:
          input:
            consumer:
              ttl: 2000 # 默认不做限制,即无限。消息在队列中最大的存活时间。当消息滞留超过ttl时,会被当成消费失败消息,即会被转发到死信队列或丢弃.
                # DLQ相关
              autoBindDlq: true # 是否自动声明死信队列(DLQ)并将其绑定到死信交换机(DLX)。默认是false。
              deadLetterExchange: mqTestDead #绑定exchange
              deadLetterQueueName:  #死信队列名字:exchanName.queueName

TTL就是配置消息的消费时间,如果超过则列为死信队列里头。
deadLetterExchange指定绑定的交换器,下面那个队列名其实可以不用配置还是会分配到交互器对应的队列里头进行消费。

show y the code

在消费时进行延迟消费

int i = 0;

    // 监听 binding 为 Processor.INPUT 的消息
    @StreamListener(Processor.INPUT)
    public void input(Message<String> message) throws Exception {
        if (i <= 1) {
            Thread.sleep(5000);
            i++;
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(System.currentTimeMillis()) + " " + "一般监听收到:" + message.getPayload());
    }

定义死信消费渠道

interface DeadProcessor {

    String INPUT_ORDER = "inputDead";
    String OUTPUT_ORDER = "outputDead";

    @Input(INPUT_ORDER)
    SubscribableChannel inputOrder();

    @Output(OUTPUT_ORDER)
    MessageChannel outputOrder();
}

相关配置

还有关于死信相关配置,在上面

spring:
  cloud:
    stream:
      defaultBinder:
      bindings:
        inputDead:
          destination: mqTestDead
        outputDead:
          destination: mqTestDead

定义死信队列消费的逻辑

@StreamListener(DeadProcessor.INPUT_ORDER)
    public void inputDead(Message<String> message) throws Exception {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(System.currentTimeMillis()) + " " + "一般监听收到死信:" + message.getPayload());
        //throw new RuntimeException();
    }

输出

2020-01-27 10:54:16 一般监听收到死信:大家好
2020-01-27 10:54:16 一般监听收到死信:大家好
2020-01-27 10:54:16 一般监听收到死信:大家好
2020-01-27 10:54:16 一般监听收到死信:大家好
2020-01-27 10:54:16 一般监听收到死信:大家好
2020-01-27 10:54:19 一般监听收到:大家好

RabbitMQ控制台
在这里插入图片描述

github

点我查看代码

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值