我无法处理来自IBM MQ的大型消息,并收到以下错误:
JMSCMQ0001: WebSphere MQ调用失败,compcode为“%1”(“MQCC_WARNING”),原因为“2080”(“MQRC_TRUNCATED_MSG_FAILED”)
我使用的是DefaultListenerContainer,而不是直接使用IBM MQ Java API类的MessageConsumer。我相信通过使用IBM MQ JMS API,您可以在从队列中检索消息之前指定特定的选项。但是我该如何使用DefaultListenerContainer来实现这一点呢?有没有可以为它们设置的系统属性?
如果使用IBM MQ JMS API(我不会像这样使用消息,仅供参考):
新建MQGetMessageOptions = mqGetMessageOptions MQGetMessageOptions();mqGetMessageOptions.waitInterval = ipreoProperties.getMqReceiveWaitTime();mqGetMessageOptions.options = MQC.MQGMO_WAIT | MQC.MQPMO_SYNCPOINT | MQC.MQGMO_ACCEPT_TRUNCATED_MSG;
下面是我的IBM MQ连接的Java配置:
@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();
}
感谢你的帮助,谢谢。
发布于 2020-11-27 03:21:34
添加延迟响应,因为它可能对某些人有用。
在我的例子中,当java客户端出现这个异常时,我们注意到实际的消息大小大于默认的4MB缓冲区大小。
Java API不提供用于更改缓冲区大小的挂钩。因此,必须在MQ服务器级别更新缓冲区大小。
首先,我们在队列属性中增加了消息大小-它不起作用。
然后,我们还增加了MQ通道级别的消息大小属性,这最终解决了问题。
总之,增加了MQ服务器上队列和通道的缓冲区大小。
发布于 2015-12-21 05:13:54
在与队列管理器的客户端连接上,您可以限制服务器和客户端的消息大小。当客户端的限制小于消息的大小时,我见过这个错误。
我不知道如何在JMS客户端中直接设置消息大小限制,但您可以使用客户端通道定义表。它是一个包含连接到队列管理器的详细信息的文件,在队列管理器上创建,然后复制到客户端主机。您需要通过在连接工厂上发出setCCDTURL来引用该文件(使用CCDT时不需要设置主机、端口和通道,CCDT会指定它们)。
在队列管理器上创建CCDT时,需要在客户端通道上设置适当的消息大小限制。
服务器端限制是在服务器连接通道上设置的。
发布于 2015-12-21 18:30:31
在JMS客户端代码中,接收缓冲区的处理是自动处理的;其原理是JMS应用程序永远不应该接收特定的错误。
第一段代码是Java Classes API,这可能会导致该错误。
这些消息到底有多大?您使用的是什么级别的JMS客户端代码-请确保它是最新版本。当然也是7.5或8版本中的一个。
这个answer也有更多关于这方面的信息。
https://stackoverflow.com/questions/34377185
复制相似问题