首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定MQ消息队列何时为空(已读取所有消息)

确定MQ消息队列何时为空(已读取所有消息)
EN

Stack Overflow用户
提问于 2016-03-31 14:19:52
回答 2查看 4.4K关注 0票数 0

我正在使用Spring创建一个错误监控工具,我目前正在从队列中读取消息并记录错误。我想要的角度是将错误队列中的所有消息存储到一个映射中。地图的关键基本上是错误信息,值是计数,因为我们想知道其中有多少。当所有消息都被读取并且队列上有0条消息时,我想运行应用程序的文件创建部分,并最终终止应用程序。

我遇到过这样的帖子:Check MQ queue depthHow to check whether have message in the queueWebsphere 7 MQueue: how to access queue depth from Java?

我已经尝试了其中的每一个霍奇波奇,也查看了IBM的知识中心,但没有取得任何成功。这是我目前拥有的:

代码语言:javascript
复制
public int depthOfQueue() throws MQException {
        queueManager = new MQQueueManager(queueManagerName); // fails here
        MQQueue queue = queueManager.accessQueue(queueName, CMQC.MQOO_OUTPUT);
        int depth = queue.getCurrentDepth();
        queueManager.disconnect();
        queue.close();
        return depth;
    }

但在我的日志中,我得到了堆栈跟踪,比如:

代码语言:javascript
复制
java.lang.NoClassDefFoundError: Could not initialize class com.ibm.mq.internal.MQCommonServices
    at com.ibm.mq.MQSESSION.getJmqiEnv(MQSESSION.java:142) ~[com.ibm.mq-7.0.1.9.jar:7.0.1.9 - k701-109-120705]
    at com.ibm.mq.MQQueueManagerFactory.<init>(MQQueueManagerFactory.java:85) ~[com.ibm.mq-7.0.1.9.jar:7.0.1.9 - k701-109-120705]
    at com.ibm.mq.MQQueueManagerFactory.getInstance(MQQueueManagerFactory.java:112) ~[com.ibm.mq-7.0.1.9.jar:7.0.1.9 - k701-109-120705]
    at com.ibm.mq.MQQueueManager.<clinit>(MQQueueManager.java:156) ~[com.ibm.mq-7.0.1.9.jar:7.0.1.9 - k701-109-120705]
    at org.mycom.casts.MQReader.depthOfQueue(MQReader.java:56) ~[classes/:?]
    at org.mycom.casts.MQReader.processOrder(MQReader.java:36) ~[classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_74]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_74]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_74]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_74]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:198) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:116) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:90) ~[spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:66) ~[spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:721) ~[spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:681) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_74]

代码语言:javascript
复制
java.lang.NoClassDefFoundError: Could not initialize class com.ibm.mq.MQQueueManager
    at org.mycom.casts.MQReader.depthOfQueue(MQReader.java:56) ~[classes/:?]
    at org.mycom.casts.MQReader.processOrder(MQReader.java:36) ~[classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_74]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_74]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_74]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_74]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:198) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:116) ~[spring-messaging-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:90) ~[spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:66) ~[spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:721) ~[spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:681) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_74]

我已经读到,我可能缺少MQ的依赖项,但是我的pom中有我需要的东西。我还读到,我可以下载MQ (或其他什么)的客户端版本,而不能这样做。

正如有人在这篇文章中指出的:IBM MQ getCurrentDepth requires accessQueue

最后,不应该需要在MQ应用程序中使用getCurrentDepth方法。您要么得到一个消息,要么循环,直到用MQException (2033年)原因代码抛出一个MQRC_NO_MSG_AVAILABLE。

所以我的问题是。我如何解决抛出的异常(也许我忽略了一些东西),或者检查MQException MQRC_NO_MSG_AVAILABLE (2033)的最佳方法是什么?因为这也应该是队列为空的信号。

最后,我使用带有注释的Spring来设置队列并从队列中读取,所有这些都正常工作,我只需要知道队列何时为空。

以防万一,这里是侦听器方法:

代码语言:javascript
复制
@JmsListener(destination = "${mq.queueName}")
public void processOrder(String message) throws MQException {
    int messageCount = depthOfQueue();  //problem line
    String messageType = "";
    if(message.startsWith("MSH|") && message.contains("ZER|")){
        messageType = "HL7";
        manager.filterMessage(messageType, message);
    } else if (message.contains(""/*ADD XML CHECK HERE*/)) {
        messageType = "XML";
        manager.filterMessage(messageType, message);
    } else {
        logger.error("Message:\n"+message+"\n does not meet conditions for error");
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-01 15:13:59

todji针对这一解决方案指出了重要的注意事项:

注意:您的用户需要在队列上获得inq权限才能工作:setmqaut -m QM1 -n Q1 -t queue -p mq-app +inq

实际上,对于任何研究同一问题的人来说,我从这两种方法中获得了所需的功能。

代码语言:javascript
复制
public int depthOfQueue() throws MQException {
        queueManager = createQueueManager();
        int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT | MQConstants.MQOO_INQUIRE;
        MQQueue queue = queueManager.accessQueue(queueName, openOptions);
        int depth = queue.getCurrentDepth();
        queueManager.disconnect();
        queue.close();
        return depth;
    }

代码语言:javascript
复制
@SuppressWarnings("unchecked")
    public MQQueueManager createQueueManager() throws MQException {
        MQEnvironment.port = port;
        MQEnvironment.hostname = host;
        MQEnvironment.channel = channel; 
        MQEnvironment.properties.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES);
        return new MQQueueManager(queueManagerName);
    }

使用这些方法:

导入com.ibm.mq.*;导入com.ibm.mq.constants.MQConstants;

您将需要pom中适当的依赖项:

代码语言:javascript
复制
<dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>com.ibm.mq</artifactId>
            <version>7.0.1.9</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>com.ibm.mq.headers</artifactId>
            <version>7.0.1.9</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>com.ibm.mq.commonservices</artifactId>
            <version>7.0.1.9</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>com.ibm.mq.pcf</artifactId>
            <version>7.0.1.9</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>com.ibm.mqjms</artifactId>
            <version>7.0.1.9</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>com.ibm.mq.jmqi</artifactId>
            <version>7.0.1.9</version>
        </dependency>
        <dependency>
            <groupId>com.ibm.mq</groupId>
            <artifactId>dhbcore</artifactId>
            <version>7.0.1.9</version>
        </dependency>
        <dependency>
            <groupId>javax.resource</groupId>
            <artifactId>connector</artifactId>
            <version>1.0</version>
        </dependency>

也许是个更好的方法,但这会完成任务的。

票数 2
EN

Stack Overflow用户

发布于 2016-04-01 06:57:00

您的类路径上没有必需的MQ JAR。pom中有JAR是一回事,但是Maven存储库中也有JAR吗?

如果您正在使用JMS,那么这些是您需要的JAR:.htm

您只需要MQ客户端从它的安装目录中获取MQ JAR。如果您可以从服务器或Maven存储库获得MQ JAR,那么您就不需要客户机了。

关于您最初的问题,您应该首先决定您将使用哪个MQ,选择JMS或MQ类for,但是在您的问题中,您似乎将两者混合在一起。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36336087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档