RabbitMQ死信队列模拟超时订单取消

136 阅读1分钟

死信交换机和队列


@Configuration
public class DeadConfig {
    //死信交换机
    @Bean
    public DirectExchange order_dead_Exchange() {
        return new DirectExchange("order_dead_Exchange", true, false);
    }

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

    @Bean
    public Binding OrderDeadBinding() {
        return BindingBuilder.bind(OrderDead()).to(order_dead_Exchange()).with("dead");
    }
}

订单交换机和队列

@Configuration
public class RabbitMqConfig {


    @Bean
    public DirectExchange order_direct_Exchange() {
        return new DirectExchange("order_direct_Exchange", true, false);
    }


    @Bean
    public Queue OrderInfo() {
        Map<String, Object> rule = new HashMap<>();
        rule.put("x-message-ttl", 10000);
        rule.put("x-dead-letter-exchange", "order_dead_Exchange");
        rule.put("x-dead-letter-routing-key","dead");
        return new Queue("OrderInfo", true, false, false, rule);
    }

    @Bean
    public Binding OrderBinding() {
        return BindingBuilder.bind(OrderInfo()).to(order_direct_Exchange()).with("info");
    }
}

下单

    public String Buy(int id, int num) {
        Commodity commodity = commodityMapper.selectById(id);
        double price = commodity.getPrice() * num;
        String orderId = UUID.randomUUID().toString();
        int flag = orderMapper.insert(new Order(orderId, id, price, 0));
        rabbitTemplate.convertAndSend(exchange, routingKey, orderId);
        return "下单状态:" + flag;
    }
}

死信队列的消费者

@Component
@RabbitListener(queues = {"OrderDead"})
public class OrderDeadConsumer {

    @Autowired
    private OrderService orderService;

    @RabbitHandler
    public void getMsg(String s) throws IOException {
        log.info("过期订单id:" + s);
        //未支付state:0 / 等待支付state:1 / 已支付state:2
        orderService.updateState(s, 0);
    }

}

这里的ack使用的默认auto,但我感觉应答写成手动的比较安全。