配置
# rabbitmq订单支付超时队列名
rabbitmq.order.pay.overtime.queue.name=order-pay-overtime-queue
# rabbitmq订单支付超时交换机名
rabbitmq.order.pay.overtime.exchange.name=order-pay-overtime-exchange
# rabbitmq订单支付超时路由键名
rabbitmq.order.pay.overtime.binding.key=order-pay-overtime-key
# rabbitmq订单支付超时死信队列名
rabbitmq.order.pay.overtime.dead.queue.name=order-pay-overtime-dead-queue
# rabbitmq订单支付超时死信交换机名
rabbitmq.order.pay.overtime.dead.exchange.name=order-pay-overtime-dead-exchange
# rabbitmq订单支付超时死信路由键名
rabbitmq.order.pay.overtime.dead.binding.key=order-pay-overtime-dead-key
# 订单支付超时时间[单位(秒)]15秒
seckill.order.pay.overtime=15
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
/**
* Rabbit配置
*
* @author Zhenfeng Li
* @version 1.0
* @date 2020-12-24 10:45
*/
@Configuration
public class RabbitConfig {
@Value("${rabbitmq.order.pay.overtime.queue.name}")
private String orderPayOvertimeQueueName;
@Value("${rabbitmq.order.pay.overtime.exchange.name}")
private String orderPayOvertimeExchangeName;
@Value("${rabbitmq.order.pay.overtime.binding.key}")
private String orderPayOvertimeBindingKey;
@Value("${rabbitmq.order.pay.overtime.dead.queue.name}")
private String orderPayOvertimeDeadQueueName;
@Value("${rabbitmq.order.pay.overtime.dead.exchange.name}")
private String orderPayOvertimeDeadExchangeName;
@Value("${rabbitmq.order.pay.overtime.dead.binding.key}")
private String orderPayOvertimeDeadBindingKey;
@Value("${order.pay.overtime}")
private Long orderPayOvertime;
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));
return rabbitTemplate;
}
@Bean(name = "rabbitListener")
public SimpleRabbitListenerContainerFactory listenerContainer(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));
return factory;
}
/**
* 订单超时死信队列
*/
@Bean("orderPayOvertimeDeadQueue")
public Queue orderPayOvertimeDeadQueue() {
return new Queue(orderPayOvertimeDeadQueueName);
}
/**
* 订单超时死信交换机
*/
@Bean("orderPayOvertimeDeadExchange")
public Exchange orderPayOvertimeDeadExchange() {
return new DirectExchange(orderPayOvertimeDeadExchangeName);
}
/**
* 绑定 订单超时死信队列->订单超时死信交换机
*/
@Bean
public Binding orderPayOvertimeDeadBinding(@Qualifier("orderPayOvertimeDeadQueue") Queue deadQueue, @Qualifier("orderPayOvertimeDeadExchange") Exchange deadExchange) {
return BindingBuilder.bind(deadQueue).to(deadExchange).with(orderPayOvertimeDeadBindingKey).noargs();
}
/**
* 订单超时队列
*/
@Bean
public Queue orderPayOvertimeQueue() {
HashMap<String, Object> hashMap = new HashMap<>(3);
//定义消息存活时间15秒
hashMap.put("x-message-ttl", orderPayOvertime * 1000);
//设置此队列产生的死信会投递给哪个交换机
hashMap.put("x-dead-letter-exchange", orderPayOvertimeDeadExchangeName);
//设置死信投递时使用的路由键
hashMap.put("x-dead-letter-routing-key", orderPayOvertimeDeadBindingKey);
return QueueBuilder.durable(orderPayOvertimeQueueName).withArguments(hashMap).build();
}
/**
* 订单超时交换机
*/
@Bean("orderPayOvertimeExchange")
public Exchange orderPayOvertimeExchange() {
return new DirectExchange(orderPayOvertimeExchangeName);
}
/**
* 绑定 订单超时队列->订单超时交换机
*/
@Bean("orderPayOvertimeBinding")
public Binding orderPayOvertimeBinding(@Qualifier("orderPayOvertimeQueue") Queue deadQueue, @Qualifier("orderPayOvertimeExchange") Exchange deadExchange) {
return BindingBuilder.bind(deadQueue).to(deadExchange).with(orderPayOvertimeBindingKey).noargs();
}
/**
* 秒杀订单超时队列
*/
@Bean
public Queue seckillOrderPayOvertimeQueue() {
HashMap<String, Object> hashMap = new HashMap<>(3);
//定义消息存活时间15秒
hashMap.put("x-message-ttl", seckillOrderPayOvertime * 1000);
//设置此队列产生的死信会投递给哪个交换机
hashMap.put("x-dead-letter-exchange", orderPayOvertimeDeadExchangeName);
//设置死信投递时使用的路由键
hashMap.put("x-dead-letter-routing-key", orderPayOvertimeDeadBindingKey);
return QueueBuilder.durable(seckillOrderPayOvertimeQueueName).withArguments(hashMap).build();
}
}
消息生产者
import com.citrsw.shangshangpin.entity.Order;
import com.citrsw.shangshangpin.entity.Product;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.time.LocalDateTime;
/**
* 消息生产者
*
* @author Zhenfeng Li
* @version 1.0
* @date 2020-12-24 12:00
*/
@Component
public class ProducerService {
private final RabbitTemplate rabbitTemplate;
@Value("${rabbitmq.order.pay.overtime.exchange.name}")
private String orderPayOvertimeExchangeName;
@Value("${rabbitmq.order.pay.overtime.binding.key}")
private String orderPayOvertimeBindingKey;
public ProducerService(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
/**
* 订单支付倒计时
*/
@Async
public void orderPayOvertimeProducer(Long orderId) {
rabbitTemplate.setExchange(orderPayOvertimeExchangeName);
rabbitTemplate.setRoutingKey(orderPayOvertimeBindingKey);
rabbitTemplate.convertAndSend(orderId, message -> {
MessageProperties mp = message.getMessageProperties();
mp.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
mp.setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, Long.class);
return message;
});
}
}
消息消费者
import com.citrsw.shangshangpin.entity.Order;
import com.citrsw.shangshangpin.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
/**
* 消息消费者
*
* @author Zhenfeng Li
* @version 1.0
* @date 2020-12-24 12:00
*/
@Component
@Slf4j
public class Consumer {
private final OrderService orderService;
public Consumer(OrderService orderService) {
this.orderService = orderService;
}
/**
* 订单超时死信队列监听
*/
@RabbitListener(queues = {"${rabbitmq.order.pay.overtime.dead.queue.name}"}, containerFactory = "rabbitListener")
public void orderPayOvertimeDeadListener(@Payload Long orderId) {
//查询订单
Order order = orderService.getById(orderId);
if (order.getStatus() < 110) {
//取消订单
orderService.cancelOrder(order);
}
}
}