我正在尝试使用Spring Boot和ActiveMQ使用JmsTemplate发送具有不同优先级的消息,但是它不起作用。
我尝试过:
MessageCreator mc = session -> {
TextMessage tm = session.createTextMessage("hello");
tm.setJMSPriority(6);
return tm;
};
jmsTemplate.send((Queue) () -> "box", mc);
ActiveMQ代理内部的优先级仍然为4(默认值)。
我发现真正更改消息优先级的唯一方法是在JmsTemplate级别上更改优先级。
jmsTemplate.setPriority(3);
这里的问题是,此后发送的所有消息的优先级都为3。 我知道我可以在每次发送后重置JmsTemplate优先级,但这不是“干净的”,并发又如何呢?
如何设置每个邮件的优先级,并使用@JmsListener获取优先级最高的邮件?
答案 0 :(得分:0)
我只是遇到了同样的问题。
我测试了您关于设置jmsTemplate优先级的观点,您的假设是正确的。并发处理不正确。
我发现可行(虽然不理想)的解决方案是扩展JmsTemplate并重写doSend方法,以将JmsPriority从消息复制到生产者。这不是理想的选择,它扩展了Spring Boot发行版中的make类突破(我已经在2.1.7上进行了测试),并且还有一些其他步骤来注册新的JmsTemplate。但这确实有效,我已经在负载下对其进行了测试。
步骤.....
创建一个扩展JmsTemplate的新类,该类重写doSend方法以从消息中复制优先级
import java.io.Serializable;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import org.springframework.jms.core.JmsTemplate;
public class RcsJmsTemplate extends JmsTemplate implements Serializable {
public RcsJmsTemplate() {
}
public RcsJmsTemplate(ConnectionFactory connectionFactory) {
super(connectionFactory);
}
/**
* Actually send the given JMS message.
*
* AF: EXTENDED TO COPY THE PRIORITY FROM THE MESSAGE TO THE PRODUCER
*
* @param producer the JMS MessageProducer to send with
* @param message the JMS Message to send
* @throws JMSException if thrown by JMS API methods
*/
@Override
protected void doSend(MessageProducer producer, Message message) throws JMSException {
if (getDeliveryDelay() >= 0) {
producer.setDeliveryDelay(getDeliveryDelay());
}
producer.send(message, getDeliveryMode(), message.getJMSPriority(), getTimeToLive());
}
}
添加一个bean(到您的App.java或适当的配置类中)您可能不需要通过消息转换器(我在项目中使用Jackson),可能还需要将其他配置应用于新的JmsTemplate
@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
RcsJmsTemplate rcsJmsTemplate = new RcsJmsTemplate(connectionFactory);
rcsJmsTemplate.setMessageConverter(messageConverter);
return rcsJmsTemplate;
}
然后按照您的问题设置消息的JmsPriority属性。您使用的是MessageCreator,但在我的项目中,我使用的是消息发布流程
public void convertAndSendWithPriority(JmsTemplate jmsTemplate, String destination, Object message, int priority) {
jmsTemplate.convertAndSend(destination, message, (Message jmsMessage) -> {
jmsMessage.setJMSPriority(priority);
return jmsMessage;
});
}
为完整起见,您应该添加属性: spring.jms.template.qos-enabled = true
就这样。希望能帮助到你 (实际上,我希望有人能提供更好的答案) 谢谢