1.创建生产者--bookStoreProduct
@Component
public class BookStoreProduct {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(String msg,String routingKey,int delayTime){
rabbitTemplate.convertAndSend("customExchange",routingKey,msg, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setDelay(delayTime);
return message;
}
});
}
}
2.创建配置类
配置消费者队列,交换机,并将消费者绑定交换机
@Configuration
public class RabbitMqConfig {
//定义延时队列
@Bean
public Queue delayQueue(){
return QueueBuilder.durable("addKill").build();
}
@Bean
public Queue deleteQueue(){
return QueueBuilder.durable("deleteKill").build();
}
@Bean
public Queue delOrder(){
return QueueBuilder.durable("delOrder").build();
}
/**
* //定义一个交换机,其实就是direct、fauout、其中一种
* @return
*/
@Bean
public CustomExchange customExchange(){
Map map=new HashMap();
map.put("x-delayed-type","direct");
/**
* arg1:交换机名字
* args2:指定消息是延时消息
* arg3:此交换机是否持久化
* arg4:是否自动删除(没有列队和该交换机绑定,是否删除)
* arg5:初始化数据
*
*/
return new CustomExchange("customExchange","x-delayed-message",true,false,map);
}
//绑定交换机和列队
@Bean
public Binding delayQueueToCustomExchange(Queue delayQueue,
CustomExchange customExchange){
return BindingBuilder.bind(delayQueue).to(customExchange).with("killBook").noargs();
}
//绑定交换机和列队
@Bean
public Binding deleteQueueToCustomExchange(Queue deleteQueue,
CustomExchange customExchange){
return BindingBuilder.bind(deleteQueue).to(customExchange).with("deleteKill").noargs();
}
//绑定交换机和列队
@Bean
public Binding delOrderToCustomExchange(Queue delOrder,
CustomExchange customExchange){
return BindingBuilder.bind(delOrder).to(customExchange).with("delOrder").noargs();
}
}
3.消费者队列--添加秒杀商品的队列
@Component
public class AddKillConsume {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@RabbitListener(queues = "addKill")
public void addKill(String msg, Message message, Channel channel){
try {
//拿到消息
KillBook killBook = JSON.parseObject(msg, KillBook.class);
//做业务
redisTemplate.opsForHash().put("killBook",String.valueOf(killBook.getId()),killBook);
//确认消息
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
} catch (IOException e) {
// throw new RuntimeException(e);
try {
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
}
4.延时业务-service
计算时间,如果超出时间,调用延时队列,执行任务
//格式化时间
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//秒杀开始时间格式化
Date startDate = simpleDateFormat.parse(killBook.getStartTime());
long timSun = startDate.getTime() - new Date().getTime();
if(timSun>60*60*1000L){
//调用延时列队
//计算出ttl时间(延时的时间)
long ttl=timSun-60*60*1000L;
bookStoreProduct.send(JSON.toJSONString(killBook),"killBook",(int)ttl);
}else {
redisTemplate.opsForHash().put("killBook", String.valueOf(killBook.getId()), killBook);
//计算出书籍秒杀结束的ttl时间
Date parse = simpleDateFormat.parse(killBook.getEndTime());
long ttl = parse.getTime() - new Date().getTime();
bookStoreProduct.send(JSON.toJSONString(killBook),"deleteBook",(int)ttl);
}
} catch (ParseException e) {
throw new RuntimeException(e);
}