【问题标题】:JMS to receive message- MQ Error code 2024 - message from queue are not getting removedJMS 接收消息 - MQ 错误代码 2024 - 来自队列的消息没有被删除
【发布时间】:2018-03-14 14:33:37
【问题描述】:

我正在使用 websphere 应用服务器 8.5

我已尝试从队列接收消息。队列可能包含多条消息。我想一口气读完。

虽然我阅读了消息,但我收到错误 WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2024' ('MQRC_SYNCPOINT_LIMIT_REACHED')。

  1. 我应该调用会话的 commit() 方法吗?如果是这样,我应该在 while 循环内为每条消息调用还是在 while 循环外调用?

  2. createQueueSession(true, 0): Producer 和 Consumer 端在这个方法中传递的参数会不会有更正?

方法:

import javax.naming.InitialContext;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.QueueSession;
import javax.jms.QueueReceiver;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;

public class Receiver
{
    @Resource(lookup = "jms/ConnectionFactory")
    private static QueueConnectionFactory connectionFactory;

    @Resource(lookup = "jms/Queue")
    private static Queue queue;

    public void readQueueMessages() {                                                                   
        try {
            // create a queue connection
            QueueConnection queueConn = connFactory.createQueueConnection();

            // create a queue session
            QueueSession queueSession = queueConn.createQueueSession(true, 0);

            // create a queue receiver
            QueueReceiver queueReceiver = queueSession.createReceiver(queue);

            // start the connection
            queueConn.start();

            // receive a message
            while(true) {
                TextMessage message = (TextMessage) queueReceiver.receive(180000);
                if (message != null) { 
                    if (message instanceof TextMessage) {
                        // print the message
                        System.out.println("received: " + message.getText());
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            }
        } catch(JMSException exp) {
            // Handle this exception
        } finally {      
            if(queueConn != null) {                                                     
                // close the queue connection
                queueConn.close();
            }
        }
    }
}

【问题讨论】:

    标签: jakarta-ee jms ibm-mq


    【解决方案1】:

    队列管理器有一个参数MAXUMSGS,它是任何客户端的最大未提交消息,默认值为10000。当您收到MQRC_SYNCPOINT_LIMIT_REACHED 时,这意味着您已达到该限制。

    通常,您会在处理完消息后提交,在您的示例中,这将是在打印出来之后。由于所有持久性消息都写入磁盘并且磁盘会减慢速度,因此您可以通过一次提交多条消息来调整性能。请记住,如果您的程序在提交消息之前崩溃,它们将回滚到队列中并在您下次启动程序时进行处理,因此您可能希望限制未提交消息的数量。


    由于您使用的是 WebSphere Application Server,因此您应该考虑使用 MDB,而不是自己编写。 MDB 将连接到队列并等待消息,从队列中读取它们并将它们分派给您自己的onMessage Java 方法来处理消息。

    我进行了搜索,这里有几个链接可能会有所帮助,我相信您可以找到其他讨论如何设置 MDB 的链接:

    1. Chris Andrews 介绍了一个会话“Using IBM WebSphere Application Server and IBM WebSphere MQ Together
    2. Craig St. Jean 有一篇博文“WebSphere 8.5, MQ, Spring, and Message-Driven Beans! Part 1

    【讨论】:

    • 如果我使用我的帖子中提到的 JMS,你说提交应该在我的示例中提到的打印消息之后正常进行。但是在 JMS 中,我如何通过一次提交多个消息来调整性能?
    • @AlagammalP 调整的需要实际上取决于您正在处理的消息量和底层存储的速度。由于各种原因,存储速度可能会成为瓶颈,例如,如果底层存储正在通过网络同步复制到另一个站点。当您发出提交时,队列管理器必须写入存储。如果您等待并提交 5 条消息,MQ 只需向磁盘写入一次即可提交所有 5 条消息。
    • @AlagammalP 如果 3 分钟内没有消息,您的示例将退出循环,您可以保留已处理的消息计数并基于此提交,例如提交 5 条消息或何时提交超时过期,如果(count % 5) == 0 在循环提交内,如果(count % 5) != 0 在循环提交外。
    • 我们是否需要在使用 JMS API 从队列中读取/使用/获取消息时提交?因为在发布消息时我没有提交?会不会是因为 put 时那些未提交的消息?
    • 您需要在使用事务会话时调用 commit。无论您是发送消息还是接收消息都无关紧要。
    猜你喜欢
    • 2011-04-25
    • 2012-01-19
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    相关资源
    最近更新 更多