Spring JMS + IBM MQ: Как установить размер буфера сообщений или время ожидания?
Я не могу обработать большие сообщения от IBM MQ и получить следующую ошибку:
JMSCMQ0001: сбой вызова WebSphere MQ с кодом компоновки '1' ('MQCC_WARNING'), причина '2080' ('MQRC_TRUNCATED_MSG_FAILED')
Я использую DefaultListenerContainer и не потребляю через MessageConsumer, использующий классы Java API IBM MQ напрямую. Я полагаю, что с помощью IBM MQ JMS API вы можете указать конкретные параметры перед извлечением сообщения из очереди. Но как мне сделать это с DefaultListenerContainer, есть ли системное свойство, которое я могу установить для них?
При использовании IBM MQ JMS API (я не использую подобное сообщение, вставленное только для справки):
MQGetMessageOptions mqGetMessageOptions = new MQGetMessageOptions (); mqGetMessageOptions.waitInterval = ipreoProperties.getMqReceiveWaitTime (); mqGetMessageOptions.options = MQC.MQGMO_WAIT | MQC.MQPMO_SYNCPOINT | MQC.MQGMO_ACCEPT_TRUNCATED_MSG;
Ниже моя конфигурация Java для соединения IBM MQ:
@Bean
public CachingConnectionFactory ipreoMQCachingConnectionFactory() {
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
//Not defining MQQueueConnectionFactory as separate bean as Spring boot's auto-configuration finds two instances
//of ConnectionFactory and throws ambiguous implementation exception
//One implementation is CachingConnectionFactory and other one would be MQQueueConnectionFactory if defined separately
MQQueueConnectionFactory mqConnectionFactory = new MQQueueConnectionFactory();
try {
mqConnectionFactory.setHostName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_HOSTNAME));
mqConnectionFactory.setQueueManager(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_QUEUE_MGR));
mqConnectionFactory.setPort(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_PORT, Integer.class));
mqConnectionFactory.setChannel(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_MQ_CHANNEL));
//mqConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
//Setting connection mode as Client so it doesn't complain for native IBM MQ libraries
mqConnectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT);
} catch (JMSException exception) {
exception.printStackTrace();
}
cachingConnectionFactory.setTargetConnectionFactory(mqConnectionFactory);
//Setting session caching size as 10, don't think we need more
cachingConnectionFactory.setSessionCacheSize(10);
cachingConnectionFactory.setReconnectOnException(true);
return cachingConnectionFactory;
}
public DefaultMessageListenerContainer ipreoDealActivityListenerContainer() {
DefaultMessageListenerContainer factory = new DefaultMessageListenerContainer();
factory.setConnectionFactory(ipreoMQCachingConnectionFactory());
factory.setDestinationName(env.getRequiredProperty(AppEnvPropertyConstants.JmsConstants.IPREO_DEAL_QUEUE_NAME));
factory.setMessageListener(ipreoDealActivityListener());
factory.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
return factory;
}
@Bean
public MessageListener ipreoDealActivityListener() {
return new IpreoDealActivityListener();
}
Спасибо за помощь, спасибо.
2 ответа
Добавление запоздалого ответа, так как это может быть кому-то полезно.
В моем случае, когда у java-клиента было это исключение, мы заметили, что фактический размер сообщения был больше, чем размер буфера по умолчанию 4 МБ.
API Java не предоставляет возможности для изменения размера буфера. Следовательно, размер буфера необходимо обновлять на уровне сервера MQ.
Во-первых, в свойствах очереди увеличили размер сообщения - не вышло.
Затем мы увеличили свойство размера сообщения на уровне канала MQ, что, наконец, решило проблему.
Подводя итог, увеличьте размер буфера на сервере MQ как для очереди, так и для канала.
В клиентском коде JMS обработка принимаемого буфера обрабатывается автоматически; Теория заключается в том, что JMS-приложение никогда не получит конкретную ошибку.
Первым фрагментом кода является API Java Classes, и это может привести к этой ошибке.
Насколько велики на самом деле эти сообщения? Какой уровень клиентского кода JMS вы используете - убедитесь, что это последняя версия. И, конечно, один из 7.5 или 8 релизов.
Этот ответ также содержит дополнительную информацию по этому вопросу.
При подключении клиента к администратору очередей вы можете ограничить размер сообщений как на стороне сервера, так и на стороне клиента. Я видел эту ошибку раньше, когда ограничение на стороне клиента было меньше, чем размер сообщения.
Я не знаю, как вы можете установить ограничение размера сообщения непосредственно в клиенте JMS, но вы могли бы использовать таблицу определения каналов клиента. Это файл, содержащий сведения для подключения к администраторам очередей, созданный в администраторе очередей и затем скопированный на хост клиента. Вам нужно сослаться на файл, выполнив setCCDTURL на фабрике соединений (установка хоста, порта и канала не требуется при использовании CCDT, CCDT определит их).
Когда CCDT создается в администраторе очередей, необходимо установить соответствующий предел размера сообщения на клиентском канале.
Ограничение на стороне сервера устанавливается на канале подключения к серверу.