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 создается в администраторе очередей, необходимо установить соответствующий предел размера сообщения на клиентском канале.

Ограничение на стороне сервера устанавливается на канале подключения к серверу.

Другие вопросы по тегам