支持消息优先级的MQ有Beanstalkd、RabbitMQ(版本3.5.0)。
支持0-255个优先级,但建议0-10个优先级。优先级对列使用时,优先级越多,对cpu和内存使用会增加。
@Configuration
public class DirectRabbitConfig {
//队列
@Bean
public Queue DirectQueue() {
Map<String, Object> map = new HashMap<>();
//一般设置10个优先级,数字越大,优先级越高
map.put("x-max-priority", 10);
return new Queue("DirectQueue", true, false, false, map);
}
//Direct交换机
@Bean
DirectExchange DirectExchange() {
return new DirectExchange("DirectExchange", true, false);
}
//将队列和交换机绑定
@Bean
Binding bindingDirect() {
return BindingBuilder.bind(DirectQueue()).to(DirectExchange()).with("DirectRouting");
}
}
给队列设置消息过期时间:
声明队列时需要设置x-message-ttl属性,并设置过期时间,推送到该队列中的所有消息,都会有一个10秒后过期的属性。
@Configuration
public class RabbitConfig {
//队列DirectQueue
@Bean
public Queue DirectQueue() {
Map<String, Object> map = new HashMap<>();
// 队列中的消息未被消费20秒过期
map.put("x-message-ttl", 20000);
return new Queue("DirectQueue", true, false, false, map);
}
//Direct交换机
@Bean
DirectExchange DirectExchange() {
return new DirectExchange("DirectExchange", true, false);
}
//将队列和交换机绑定
@Bean
Binding bindingDirect() {
return BindingBuilder.bind(DirectQueue()).to(DirectExchange()).with("DirectRouting");
}
}
指定条消息的过期时间
@RestController
public class SendMessageController {
@Autowired
RabbitTemplate rabbitTemplate;
@GetMapping("/sendMessage")
public void sendMessage() {
MessageProperties messageProperties = new MessageProperties();
//设置过期时间
messageProperties.setExpiration("10000");
//这个参数是用来做消息的唯一标识
//发布消息时使用,存储在消息的headers中
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
User user = new User(1, "张三" + 1);
Message message = new Message(JSON.toJSONString(user).getBytes(StandardCharsets.UTF_8), messageProperties);
rabbitTemplate.convertAndSend("DirectExchange", "DirectRouting", message, correlationData);
}
}
注意:
RabbitMQ只会过期淘汰队列头部的消息。如果单独给一条消息设置ttl,先入队列的消息过期时间如果设置比较长,后入队列的设置时间比较短,那么消息就不会及时的被淘汰,会导致消息的堆积问题。