SpringBoot整合RabbitMq实现订单超时关闭

RabbitMq实现订单超时取消

        
            org.springframework.boot
            spring-boot-starter-amqp
        

1、配置RabbitMq

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virtual-host: /
@Getter
public enum QueueEnum {
	/**
	 * 消息通知队列
	 */
	QUEUE_ORDER_CANCEL("mall.order.direct", "mall.order.cancel", "mall.order.cancel"),
	/**
	 * 消息通知ttl队列
	 */
	QUEUE_TTL_ORDER_CANCEL("mall.order.direct.ttl", "mall.order.cancel.ttl", "mall.order.cancel.ttl");

	/**
	 * 交换名称
	 */
	private String exchange;
	/**
	 * 队列名称
	 */
	private String name;
	/**
	 * 路由键
	 */
	private String routeKey;

	QueueEnum(String exchange, String name, String routeKey) {
		this.exchange = exchange;
		this.name = name;
		this.routeKey = routeKey;
	}
}
@Configuration
public class RabbitConfig {
	@Autowired
	private CachingConnectionFactory connectionFactory;


    /**
     * 订单消息实际消费队列所绑定的交换机
     */
    @Bean
    DirectExchange orderDirect() {
        return (DirectExchange) ExchangeBuilder
                .directExchange(QueueEnum.QUEUE_ORDER_CANCEL.getExchange())
                .durable(true)
                .build();
    }

    /**
     * 订单延迟队列队列所绑定的交换机
     */
    @Bean
    DirectExchange orderTtlDirect() {
        return (DirectExchange) ExchangeBuilder
                .directExchange(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange())
                .durable(true)
                .build();
    }

    /**
     * 订单实际消费队列
     */
    @Bean
    public Queue orderQueue() {
		Map args = new HashMap<>(2);
		args.put("x-dead-letter-exchange", QueueEnum.QUEUE_TTL_ORDER_CANCEL.getExchange());
		args.put("x-dead-letter-routing-key", QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey());
		return QueueBuilder.durable(QueueEnum.QUEUE_ORDER_CANCEL.getName()).withArguments(args).build();
    }

    /**
     * 订单延迟队列(死信队列)
     */
    @Bean
    public Queue orderTtlQueue() {
        return QueueBuilder
                .durable(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getName())
                .build();
    }

    /**
     * 将订单队列绑定到交换机
     */
    @Bean
    Binding orderBinding(DirectExchange orderDirect, Queue orderQueue){
        return BindingBuilder
                .bind(orderQueue)
                .to(orderDirect)
                .with(QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey());
    }

    /**
     * 将订单延迟队列绑定到交换机
     */
    @Bean
    Binding orderTtlBinding(DirectExchange orderTtlDirect, Queue orderTtlQueue){
        return BindingBuilder
                .bind(orderTtlQueue)
                .to(orderTtlDirect)
                .with(QueueEnum.QUEUE_TTL_ORDER_CANCEL.getRouteKey());
    }


	@Bean
	public RabbitTemplate rabbitTemplate() {
		connectionFactory.setPublisherConfirms(true);
		connectionFactory.setPublisherReturns(true);
		RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
		rabbitTemplate.setMandatory(true);
		rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
		return rabbitTemplate;
	}

	/**
	 * 单一消费者
	 * 
	 * @return
	 */
	@Bean(name = "multiListenerContainer")
	public SimpleRabbitListenerContainerFactory listenerContainer() {
		SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
		factory.setConnectionFactory(connectionFactory);
		factory.setMessageConverter(new Jackson2JsonMessageConverter());
		factory.setConcurrentConsumers(1);
		factory.setMaxConcurrentConsumers(1);
		factory.setPrefetchCount(5);
		factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
		return factory;
	}

2、发送至队列

@Component
@Slf4j
public class CancelOrderSender {
    @Autowired
    private AmqpTemplate amqpTemplate;

    public void sendMessage(String orderNumber, final long delayTimes) {
        // 给延迟队列发送消息
        amqpTemplate.convertAndSend(QueueEnum.QUEUE_ORDER_CANCEL.getExchange(),
                QueueEnum.QUEUE_ORDER_CANCEL.getRouteKey(), orderNumber, message-> {
                    message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
                return message;
        });
        log.info("send orderNumber:{}", orderNumber);
    }
}

3、消费队列消息

/**
 * 取消订单消息的处理者
 */
@Slf4j
@Component
@RabbitListener(queues = "mall.order.cancel.ttl", containerFactory = "multiListenerContainer")
public class CancelOrderReceiver {


	@RabbitHandler
	public void handle(String orderNumber, Channel channel, Message message) {
		try {
			//业务处理
		}catch (Exception e){
			try {
				channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}


	}
}

 

你可能感兴趣的:(RabbitMq,java,spring,boot,后端,消息队列)