Rabbitmq死信队列

死信队列(DLX dead-letter-exchange)

死信
(1)消息被拒绝并且没有重新放到队列中
(2)消息超时 (通过Arguments对象设置x-message-ttl Time To Live简称TTL)
(3)超过队列长度限制的消息

通过这种特性可以做延时队列。
使用场景
分布式应用系统因为发送超时情况下,通过自消费延时发送做数据同步处理。
优点:
1.可以避免专门使用定时任务做轮循操作。
2.应用系统分布式部署,起到了分布式定时任务系统作用
缺点:
无法定时定点执行。
延时队列
这里的延时队列可以通过两种方式来实现:
(1)设置消息的有效时间
(2)设置队列的有效时间,即消息没有被消费,从该队列移除。
如何设置
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.rabbitmq")
@PropertySource(value = "classpath:rabbitmq.properties")
public class RabbitMQConfig {

    org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
    
    
    private String host;
    private int port;
    private String username;
    private String password;
    private String virtualHost;

    @Bean public CachingConnectionFactory cachingConnectionFactory() {
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setHost(host);
        factory.setPort(port);
        factory.setUsername(username);
        factory.setPassword(password);
        factory.setVirtualHost(virtualHost);
        factory.setConnectionTimeout(20000);
        //开启confirm机制(确保消息能够到达Exchange)
        factory.setPublisherConfirms(true);
        //开启return机制(确保消息能够路由到Queue)
        factory.setPublisherReturns(true);
        return factory;
    }

    @Bean public RabbitAdmin rabbitAdmin(CachingConnectionFactory cachingConnectionFactory) {
        return new RabbitAdmin(cachingConnectionFactory);
    }

    //声明一个绑定有时效的Queue的Exchange
    @Bean public DirectExchange delayExchange() {
        //  1.队列名称;
        //  2.是否持久化;
        //  3.是否自动删除(没有被使用的时候,直接删除该队列)
        return new DirectExchange("delay-exchange", true, false);
    }

    //声明一个不被消费者消费的队列
    @Bean public Queue delayQueue(){
        Map map = new HashMap<>(3);
        //设置消息在队列中存活时间
        map.put("x-message-ttl", 100000);
        //设置消息成为死信后被转发到的交换机
        map.put("x-dead-letter-exchange", "dead-exchange");
        //设置交换机的路由键
        map.put("x-dead-letter-routing-key", "dead-exchange-routing-key");
        //  1.队列名称;
        //  2.是否持久化;
        //  3.是否独占(被当前连接使用);
        //  4.是否自动删除(没有被使用的时候,直接删除该队列)
        //  5.拓展参数(可以通过rabbitmq admin客户端查看有哪些参数)
        return new Queue("delay-queue", true, false, false, map);
    }

    //绑定延时队列、交换机
    @Bean public Binding delayBinding(){
        return new Binding("delay-queue", Binding.DestinationType.QUEUE,"delay-exchange" ,
                "delay-exchange-routing-key", null);
    }


    //声明死信的Exchange
    @Bean public DirectExchange deadExchange(){
        return new DirectExchange("dead-exchange", true, false);
    }

    //声明死信消费的队列
    @Bean public Queue deadQueue(){
        return new Queue("dead-queue", true, false, false);
    }

    //绑定死信队列、交换机
    @Bean public Binding deadBinding(){
        return new Binding("dead-queue", Binding.DestinationType.QUEUE,"dead-exchange" ,
                "dead-exchange-routing-key", null);
    }


    @Bean public RabbitTemplate rabbitTemplate(CachingConnectionFactory cachingConnectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
        rabbitTemplate.setConfirmCallback((CorrelationData correlationData, boolean ack, String cause) -> {
            logger.error("correlationData---->" + correlationData);
            logger.error("ack---->" + ack);
            logger.error("cause---->" + cause);
        });
        //开启强制性委托,不设置,returnCallback机制不起作用
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnCallback((Message message, int replyCode, String replyText,
                String exchange, String routingKey)->{
            logger.error("message---->" + new String(message.getBody()));
            logger.error("replyCode---->" + replyCode);
            logger.error("replyText---->" + replyText);
            logger.error("exchange---->" + exchange);
            logger.error("routingKey---->" + routingKey);
        });

        return rabbitTemplate;
    }

}

你可能感兴趣的:(MQ)