场景:业务需求,订单在指定时间后进行逻辑操作
config类中设置
/**
* 方法rabbitAdmin的功能描述:动态声明queue、exchange、routing
*
* @param connectionFactory
* @return
* @author : yuhao.wang
*/
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
//声明死信队列(Fanout类型的exchange)
Queue deadQueue = new Queue(Constants.QUEUE_NAME_DEAD_QUEUE);
// 死信队列交换机
FanoutExchange deadExchange = new FanoutExchange(Constants.MQ_EXCHANGE_DEAD_QUEUE);
rabbitAdmin.declareQueue(deadQueue);
rabbitAdmin.declareExchange(deadExchange);
rabbitAdmin.declareBinding(BindingBuilder.bind(deadQueue).to(deadExchange));
// 发放奖励队列交换机
DirectExchange exchange = new DirectExchange(Constants.MQ_EXCHANGE_SEND_AWARD);
//声明的消息队列(Direct类型的exchange)
Queue couponQueue = queue(Constants.QUEUE_NAME_SEND_COUPON);
rabbitAdmin.declareQueue(couponQueue);
rabbitAdmin.declareExchange(exchange);
rabbitAdmin.declareBinding(BindingBuilder.bind(couponQueue).to(exchange).with(Constants.MQ_ROUTING_KEY_SEND_COUPON));
return rabbitAdmin;
}
public Queue queue(String name) {
Map<String, Object> args = new HashMap<>();
// 设置死信队列
args.put("x-dead-letter-exchange", Constants.MQ_EXCHANGE_DEAD_QUEUE);
args.put("x-dead-letter-routing-key", Constants.MQ_ROUTING_KEY_DEAD_QUEUE);
// 设置队列的过期时间, 单位是毫秒
args.put("x-message-ttl", 5000);
// 是否持久化
boolean durable = true;
// 仅创建者可以使用的私有队列,断开后自动删除
boolean exclusive = false;
// 当所有消费客户端连接断开后,是否自动删除队列
boolean autoDelete = false;
return new Queue(name, durable, exclusive, autoDelete, args);
}
添加延迟消费者
@Component
public class DelayReceiver {
@RabbitListener(queues = Constants.QUEUE_NAME_DEAD_QUEUE)
public void process(String sendMessage) throws Exception {
System.out.println("收到的消息"+sendMessage);
log.info("时间({}),消息体:{}",new Date()+"", sendMessage);
}
}
发送消息测试
rabbitTemplate.convertAndSend(Constants.QUEUE_NAME_SEND_COUPON, new Date()+"");
如上,只能根据队列的过期时间,来做到延迟. 那么,如何动态的修改延迟时间?
MessageProperties properties = new MessageProperties();
properties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
//设置消息过期时间
properties.setExpiration(time);
// 当队列过期时间和消息过期时间同时存在时,按照最短的时间进行过期
Message message = new SimpleMessageConverter().toMessage(data,properties);
rabbitTemplate.send(queueName,message);