我遇到了同样的问题。
我测试了您关于设置jmsTemplate优先级的观点,您的假设是正确的。在并发方面它没有被正确处理。
我找到了一个解决方案 (虽然不是理想的),就是扩展JmsTemplate并重写doSend方法,将JmsPriority从消息复制到生产者。虽然这不是理想的,但它确实有效,并且经过了负载测试。但是这样做会破坏spring boot版本 (我已在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);
}
@Override
protected void doSend(MessageProducer producer, Message message) throws JMSException {
if (getDeliveryDelay() >= 0) {
producer.setDeliveryDelay(getDeliveryDelay());
}
producer.send(message, getDeliveryMode(), message.getJMSPriority(), getTimeToLive());
}
}
在您的App.java或适当的配置类中添加一个bean。您可能不需要通过消息转换器(我在我的项目中使用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
就这样。希望有所帮助。(实际上我希望有人能提供更好的答案)谢谢。