【问题标题】:JMS - Cannot retrieve message from queue. Happens intermittentlyJMS - 无法从队列中检索消息。间歇性发生
【发布时间】:2015-12-23 01:08:46
【问题描述】:

我们有一个 Java 类,它监听数据库 (Oracle) 队列表并在该队列中有记录时对其进行处理。它在 UAT 和开发环境中正常工作。在生产中部署时,有时它无法从队列中读取记录。插入记录时,它无法检测到它,并且记录保留在队列中。这种情况很少发生,但确实会发生。如果我要统计一下,在一天排队的 30 条记录中,大约有 8 条没有成功。我们需要重新启动整个应用程序才能读取记录。

这是我班的代码 sn-p..

public class SomeListener implements MessageListener{

public void onMessage(Message msg){
     InputStream input = null;
    try {
        TextMessage txtMsg = (TextMessage) msg;
        String text = txtMsg.getText(); 
        input = new ByteArrayInputStream(text.getBytes());
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        logger.error("Parsing from the queue.... failed",e1);
        e1.printStackTrace();
    }

    //process text message
}

}

奇怪的是,我们无法从日志中找到任何异常痕迹。

有人可以帮忙吗?顺便说一下,我们将 receiveTimeout 设置为 10 秒

【问题讨论】:

  • 监听器的代码并不重要。从队列中读取的基础设施代码应该更有趣。

标签: oracle11g jms spring-jms jmstemplate


【解决方案1】:

我们需要重新启动整个应用程序才能读取记录。

最常见的原因是侦听器线程“卡”在用户代码中 (//process text message)。您可以使用jstackjvisualvm 或类似的方式进行线程转储,以查看线程在做什么。

另一种可能性(像这样的低容量应用程序)是网络(很可能是网络中某个地方的路由器)静默关闭空闲套接字,因为它已经有一段时间没有使用了。如果容器(实际上是代理的 JMS 客户端库)不知道套接字已死,它将永远不会再收到任何消息。

第一种的解决方法是修复代码;第二种解决方案是在连接上启用某种心跳或保持活动,以便网络/路由器在没有“真实”流量时不会关闭套接字。

关于配置心跳/keepalives,您需要查阅代理的文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-25
    • 2013-10-27
    • 2013-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2011-01-13
    相关资源
    最近更新 更多