rabbitmq专题04-RabbitMq的死信队列

该博客介绍了如何在RabbitMQ中配置和使用死信队列。通过代码示例展示了生产者和消费者端的配置,包括业务队列声明死信交换机和路由键,以及消费者端的异常处理和手动确认模式。死信队列在消息消费异常时捕获并记录消息,避免数据丢失。
摘要由CSDN通过智能技术生成

    死信队列其实和普通队列一样,只不过是被正常的业务队列声明并绑定为死信队列,我们可以理解为正常业务队列的助理队列。当正常业务队列的消息在被消费的过程中,如果发生异常,那么此消息需要被记录到日志表中,这个时候可以给业务队列声明绑定一个死信队列,那么这个异常消息可以被路由到死信队列,然后死信队列的消费者监听器可以把死信队列中的消息写到日志表中记录。

 看代码:

以下代码为生产者端:

@Configuration
public class RabbitmqConfig {

   

    //业务交换机
    @Bean
    public DirectExchange defaultExchange() {
        return new DirectExchange("testExchange");
    }

    //业务队列
    @Bean
    public Queue queue() {
        Map<String, Object> map = new HashMap<>();
        //x-dead-letter-exchange    这里声明当前队列绑定的死信交换机
        map.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        //x-dead-letter-routing-key  这里声明当前队列的死信路由key
        map.put("x-dead-letter-routing-key", DEAD_LETTER_QUEUEA_ROUTING_KEY);
        return QueueBuilder.durable("jllqueue").withArguments(map).build();
    }

    //业务交换机和队列的绑定
    @Bean
    public Binding binding() {
        return BindingBuilder.bind(queue()).to(defaultExchange()).with("testRoutingKey");
    }

    //-------------------------------以下为死信队列的配置-------------------------------------
    String DEAD_LETTER_EXCHANGE = "deadExchange";
    //死信交换机
    @Bean
    public DirectExchange deadExchange() {
        return new DirectExchange(DEAD_LETTER_EXCHANGE);
    }

    //死信队列
    @Bean
    public Queue deadQueue() {
        return new Queue("deadJllQueue", true);
    }

    String DEAD_LETTER_QUEUEA_ROUTING_KEY = "testDeadRoutingKey";
    //私信队列绑定到私信交换机
    @Bean
    public Binding bindingDead() {
        return BindingBuilder.bind(deadQueue()).to(deadExchange()).with(DEAD_LETTER_QUEUEA_ROUTING_KEY);
    }
}

以下代码为消费者端:

@Configuration
public class RabbitmqConfig {

    @Bean
    public DirectRabbitListenerContainerFactory directRabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        DirectRabbitListenerContainerFactory directRabbitListenerContainerFactory = new DirectRabbitListenerContainerFactory();
        directRabbitListenerContainerFactory.setConnectionFactory(connectionFactory);
        //人工确认模式
        directRabbitListenerContainerFactory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        //消费异常拒绝重入队列,可以进入私信队列
        directRabbitListenerContainerFactory.setDefaultRequeueRejected(false);
        return directRabbitListenerContainerFactory;
    }
    
}



/**
 * 消费业务
 */
@Component
public class RabbitMqListener {
   
    @RabbitListener(queues = "jllqueue",containerFactory = "directRabbitListenerContainerFactory")
    public void consumer2(Message message, Channel channel) throws IOException {
        try {
            System.out.println("### consumer2-执行业务 ### "+message);
            int i = 10/0;
        } catch (Exception e) {
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
            return;
        }
        //手动确认,设置手动确认后,没有下面代码,那么队列中Unacked状态的数据一直存在,直到消费端服务断开时,这些数据会重新进入到Ready状态中重新消费,这样会导致重复消费
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    @RabbitListener(queues = "deadJllQueue",containerFactory = "directRabbitListenerContainerFactory")
    public void receiveB(Message message, Channel channel) throws IOException {
        System.out.println("收到死信消息:" + new String(message.getBody()));
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

荆茗Scaler

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

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

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

打赏作者

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

抵扣说明:

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

余额充值