场景:小明过年买火车票回家,费尽千辛万苦抢到一张火车票,于是,他开心地从轮椅上站了起来。万事具备,只欠东风,只要小明付款,火车票就到手了。然而,小明因为太高兴了,仰天长笑30分钟,订单失效了。因为订单在30分钟内如果没有进行支付的话,就会失效。
那么这种订单失效是如何实现的呢?
我们把订单看作是一个消息,它当然也会存放在一个消息队列中,但是这种消息会有些不一样,它是隔一定的时间才会放入消息队列中,比如订单就隔了30分钟然后进入队列,然后消费者(服务器)从消息队列中读取消息,并且删除消息,所以订单在30分钟之内没有支付就会被删除,也就是失效了。这种有延迟功能的队列称为延时队列。
订单延时删除怎么做?
分布式里的删除操作
延时队列中放的都是过期的消息,消息发送后,隔一定的时间才会进入队列。有多个消费者从中接收消息,接收到消息的消费者执行消息的删除操作。
ActiveMQ支持延时对列,RabbitMQ不支持
创建一个延时队列的方法
1. 修改activemq的配置文件
schedulerSupport="true"
,修改后,重新启动ActiveMQ
2. 发送延时消息
@Autowired
private JmsTemplate jmsTemplate;
@Test
public void dalyTask() {
ActiveMQQueue activeMQQueue = new ActiveMQQueue("order.expire.queue");
jmsTemplate.convertAndSend(activeMQQueue, "{\"id\":1}", new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws JMSException {
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10*1000);
return message;
}
});// {"id":1}
}
3. 监听延时消息,完成过期的删除
@Component
public class ExpireListener {
@JmsListener(destination="order.expire.queue")
public void onMessage(Message message) {
ActiveMQTextMessage msg = (ActiveMQTextMessage) message;
try {
String text = msg.getText();
System.out.println("本次要删除的数为:" + text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}