[英]Update: Spring Boot JMS static reply queue on IBM MQ Series
在我的用例中,我需要通過托管隊列對遠程系統進行請求-回復調用。 使用 Spring Boot 和 IBM 的 MQ 啟動器,我遇到的問題是應用程序想要創建動態/臨時回復隊列,而不是使用已經存在的托管隊列。
配置在這里設置
@EnableJms
@Configuration
public class QueueConfiguration {
@Bean
public MQQueueConnectionFactory connectionFactory() throws JMSException {
MQQueueConnectionFactory factory = new MQQueueConnectionFactory();
factory.setTransportType(CT_WMQ); // is 1
factory.setHostName(queueProperties.getHost());
factory.setPort(queueProperties.getPort());
factory.setChannel(queueProperties.getChannel()); // combo of ${queueManager}%${channel}
return factory;
}
@Bean
public JmsMessagingTemplate messagingTemplate(ConnectionFactory connectionFactory) {
JmsMessagingTemplate jmt = new JmsMessagingTemplate(connectionFactory);
jmt.setDefaultDestinationName(queueProperties.getQueueName());
return jmt;
}
@Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.foo.model");
return marshaller;
}
@Bean
public MessageConverter messageConverter(Jaxb2Marshaller marshaller) {
MarshallingMessageConverter converter = new MarshallingMessageConverter();
converter.setMarshaller(marshaller);
converter.setUnmarshaller(marshaller);
return converter;
}
}
用法非常簡單:將 object 轉換並發送。 等待響應接收並轉換它。
@Component
public class ExampleSenderReceiver {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Override
@SneakyThrows
public ResponseExample sendAndReceive(RequestExample request, String correlationId) {
MessagePostProcessor mpp = message -> {
message = MessageBuilder.fromMessage(message)
.setHeader(JmsHeaders.CORRELATION_ID, correlationId)
// .setHeader(JmsHeaders.REPLY_TO, "DEV.QUEUE.3") this triggers queue creation
.build();
return message;
};
String destination = Objects.requireNonNull(jmsMessagingTemplate.getDefaultDestinationName());
return jmsMessagingTemplate.convertSendAndReceive(destination, request, ResponseExample.class, mpp);
}
我已經閱讀了很多 IBM 文檔並認為,我需要將消息類型設置為“MQMT_REQUEST”,但我沒有找到合適的位置。
添加了Gary 建議的 Spring 集成並添加了 JmsOutboundGateway 的配置
@Bean
public MessageChannel requestChannel() {
return new DirectChannel();
}
@Bean
public QueueChannel responseChannel() {
return new QueueChannel();
}
@Bean
@ServiceActivator(inputChannel = "requestChannel" )
public JmsOutboundGateway jmsOutboundGateway( ConnectionFactory connectionFactory) {
JmsOutboundGateway gateway = new JmsOutboundGateway();
gateway.setConnectionFactory(connectionFactory);
gateway.setRequestDestinationName("REQUEST");
gateway.setReplyDestinationName("RESPONSE");
gateway.setReplyChannel(responseChannel());
gateway.setCorrelationKey("JMSCorrelationID*");
gateway.setIdleReplyContainerTimeout(2, TimeUnit.SECONDS);
return gateway;
}
並改編了我的 ExampleSenderReceiver class
@Autowired
@Qualifier("requestChannel")
private MessageChannel requestChannel;
@Autowired
@Qualifier("responseChannel")
private QueueChannel responseChannel;
@Override
@SneakyThrows
public ResponseExample sendAndReceive(RequestExample request, String correlationId) {
String xmlContent = "the marshalled request object";
Map<String, Object> header = new HashMap<>();
header.put(JmsHeaders.CORRELATION_ID, correlationId);
GenericMessage<String> message1 = new GenericMessage<>(xmlContent, header);
requestChannel.send(message1);
log.info("send done" );
Message<?> receive = responseChannel.receive(1500);
if(null != receive){
log.info("incoming: {}", receive.toString());
}
}
重要的部分是gateway.setCorrelationKey("JMSCorrelationID*");
沒有那條線,correlationId 沒有正確傳播。
下一步是重新添加 MessageConverters 並讓它再次變得更好。
謝謝你。
默認的 JmsTemplate(由JmsMessagingTemplate
使用)始終使用臨時回復隊列。 您可以對其進行子類化並覆蓋doSendAndReceive(Session session, Destination destination, MessageCreator messageCreator)
以使用您的托管隊列。
但是,它僅在您一次有一個未完成的請求時才有效(例如,所有請求都在單個線程上運行)。 您還必須通過檢查相關 id 添加用於丟棄“遲到”到達的代碼。
您可以改用異步發送並處理偵聽器容器上的回復並將回復與請求相關聯。
考慮改用spring-integration-jms
及其出站網關 - 它在回復隊列處理方面具有更大的靈活性(並為您完成所有相關性)。
https://docs.spring.io/spring-integration/reference/html/jms.html#jms-outbound-gateway
您缺少隊列管理器。
ibm:
mq:
queueManager: QM1
channel: chanel
connName: localhost(1414)
user: admin
password: admin
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.