【问题标题】:Websphere MQ Message Infinite ProcessWebsphere MQ 消息无限进程
【发布时间】:2017-01-25 06:08:02
【问题描述】:

我是消息队列的新手。我正在尝试使用以下代码从 MQ 队列获取消息。

我正在创建一个连接并使用该连接从队列中获取每条消息。这样做是否正确以及我是否需要提交连接。

无限for循环是从队列中一直接收消息的正确方法,对吗? 请给我建议。

try {
    createMQConnection(); // getting mq connection
    createMQSession(); // getting mq session
    createMQDestination(); // getting mq destination

    for ( ; ; ) { // infinite loop to receive message from Queue
        consumer = session.createConsumer(mqQueue);
        jmsTextMessage = (JMSTextMessage) consumer.receive(100);
        // Calling application method to process the requested message from queue
    }
} catch (Exception e) {
    throw e;
} finally {
    // closing consumer
    // closing session
    // closing connection
}

【问题讨论】:

  • 如果你使用没有参数的receive(),它应该等待无穷大。另外,我认为您不需要每次都创建消费者。查看来自 IBM 的示例
  • 感谢并注明。因为我正在为每个循环一个一个地读取多个队列。

标签: java jms ibm-mq


【解决方案1】:

这样的做法对吗

定义“正确”。根据业务需求,这可能是正确的,也可能是可怕的。例如,如果等待时间为 100 毫秒且消息深度为零,则代码将超时,抛出 2033 错误 (MQRC_NO_MSG_AVAILABLE),关闭会话并退出。这就是你想要的吗?

通常有一个try/catch 块包含GET,并且如果意图是即使队列为空,程序仍然运行,它也会处理像RC=2033 这样的瞬态错误。但在这种情况下,习惯上将超时设置为 10 秒左右。如果超时时间为 100 毫秒,那么编写的应用程序如果被修改为保持运行,绝对会敲击监听器。

此外,异常处理不显示任何用于打印链接异常的代码。 JMS 异常是多级数据结构,其中传输提供者的本机错误代码位于异常的链接部分中。如果错误处理不查看链接的异常,它甚至无法区分MQRC=2033(无消息)与MQRC=2035(授权错误)之间的区别。其中一个是暂时的,应该由程序幸存下来,另一个总是致命的。至少,代码应该打印链接的异常,或者打印一条消息,说明未找到链接的异常。

因此,对于循环和处理设计,如果不知道要求,就不可能回答“正确”的值。关于异常处理,绝对正确,因为不存在链接异常处理。

...以及我是否需要提交连接。

视情况而定。可以丢失或重复消息吗?如果是这样,则不需要交易。使用事务处理会话可以防止消息丢失,但不能防止受骗。使用 XA 2-Phase Commit 可以防止消息丢失和欺骗。这个想法是选择满足业务需求和相应代码的服务类别(通常称为“最多一次”、“至少一次”或“一次且仅一次”)。

无限for循环是一直从队列中接收消息的正确方法,对吗?

这是一种方法。对于高可用性和高吞吐量,通常有两个或多个应用程序实例在同一个队列上进行侦听。这样,如果一个应用服务器实例出现故障(无论是计划内还是计划外),其他实例将继续为队列提供服务。一般来说,所有这些实例都会在队列中侦听大约 10 秒的超时时间。

还有一个惯例是队列中的GET 指定MQGMO_FAIL_IF_QUIESCING,它允许QMgr 在MQ 管理员尝试关闭QMgr 时中断应用程序。如果未指定此选项,则关闭 QMgr 的唯一方法是要求它强制中断未完成的连接,并且这只能作为最后的手段。

当消息到达队列时,也可能导致 MQ 触发应用程序启动。当应用在 JEE 服务器上运行时通常不会这样做,但对于独立应用非常有用。

【讨论】:

    【解决方案2】:

    我会选择多线程应用程序,其中每个线程执行以下操作:

    1) 连接到队列管理器。

    2) 为队列创建消费者。

    3) 设置消息侦听器以异步接收消息。如果这不适合,则使用 receive() 方法进行同步消息接收。

    4) 消息消费完成后进行清理。

    这样做的好处:线程从各自的队列中接收消息并且不会因为任何原因而被阻塞。

    【讨论】:

    • 感谢并注意到Shashi.. 对不起,我不熟悉多线程应用程序。尽管我需要编写无限循环来正确获取消息以及是否需要提交连接。请告诉我
    • 您的意思是提交事务吗?关于无限循环问题 - 您可以运行一个循环,直到在队列中找不到任何消息。如果队列中没有消息,receive(
    • 注意到沙市。我的意思是 session.commit().. 当我们需要做 session.commit 的时候?我理解多线程在多队列实现时更有用。单线程足以从一个队列中逐个读取消息对吗?
    • 如果您使用事务处理会话,则需要提交,即您指定 true 作为 createSession 调用的第一个参数。见此链接:ibm.com/support/knowledgecenter/SSFKSJ_9.0.0/com.ibm.mq.dev.doc/…
    猜你喜欢
    • 1970-01-01
    • 2011-03-28
    • 2010-09-21
    • 2010-12-04
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    相关资源
    最近更新 更多