首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果在使用消息后出现错误,如何在JMS消息队列中保存消息?

如果在使用消息后出现错误,如何在JMS消息队列中保存消息?
EN

Stack Overflow用户
提问于 2015-05-15 18:43:11
回答 4查看 19.9K关注 0票数 13

我的场景是-我将消息发送到队列中,一旦消息被消耗,我就将其发送给第三方中间件应用程序。如果中间件应用程序被关闭,那么我发布的消息就会被抛出。如果中间件应用程序关闭,我不想丢失该消息,而是希望它处于等待状态或在队列中等待。请建议,如何处理这种情况?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-05-16 17:00:49

您应该创建这样的会话:

代码语言:javascript
运行
复制
Session session = connection.createSession(false,
                       Session.CLIENT_ACKNOWLEDGE);

当您试图将消息传递给第三方应用程序时:

  • 如果它有效的话,你应该对信息进行修改。
  • 如果它坏了,您不应该限制它,这样JMS提供者就能够修改它,并且消息不会丢失。message.acknowledge();

此外,您还可以查看以下内容:ACKNOWLEDGE when is it acknowledged?

票数 8
EN

Stack Overflow用户

发布于 2015-05-19 18:28:23

JMS队列不是消息存储。

如果您有一条处理继续失败的“坏消息”,那么JMS服务器(如果配置的话)将不可避免地将该消息转储到一个“死消息队列”,该队列将慢慢填满,直到另一个进程耗尽它。

您不希望将坏消息保存在队列中,因为它们可能会阻塞队列(假设您有10个用户,而前10条消息都是坏消息,所以所有进程都会继续处理坏消息-延迟队列)。

因此,您需要某种机制将消息存储到异常接收器中,然后可以将它们注入主队列进行处理。

死消息队列不是此机制(不要将消息存储在JMS队列中),而是一种将异常消息路由到更永久的存储区域(即db表或其他东西)的机制。

一旦在那里,他们可以被审查(自动,手动,任何),或者重新交付或取消。

但关键是您需要一种外部机制来实现这一点,仅是JMS服务器并不是此类消息的合适位置。

票数 7
EN

Stack Overflow用户

发布于 2015-05-19 18:13:00

这可以帮助我使用会话确认。为此,首先修改生产者代码以使用Session.AUTO_ACKNOWLEDGE。在创建队列会话时,将AUTO_ACKNOWLEDGE设置为false。这意味着消费者必须承认。当使用者发送消息确认时,消息将从队列中删除,否则它将保留在队列中。

下面是生产者代码。

代码语言:javascript
运行
复制
try {
        QueueConnectionFactory qcf = AppUtils.getQueueConnectionFactory(); 
        Queue q = AppUtils.getDestination();
        QueueConnection qConnection = qcf.createQueueConnection();
        QueueSession qSession = qConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

        QueueSender qSender = qSession.createSender(q);

        qConnection.start();
        TextMessage msg = qSession.createTextMessage("Hello");
        qSender.send(msg);

        qSender.close();
        qConnection.close();

    } catch (JMSException e) {
        // log your error to log file
        e.printStackTrace();
    }

在消费者端,您必须做同样的事情,使用AUTO_ACKNOWLEDGE创建一个队列会话,作为false。

在处理完消息后,可以发送“确认”从队列中删除消息,否则消息将保留在队列中。

代码语言:javascript
运行
复制
try {
        QueueConnectionFactory qcf = getQueueConnectionFactory(); 
        Queue q = getDestination();
        QueueConnection qConnection = qcf.createQueueConnection();
        QueueSession qSession = qConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

        QueueReceiver qReceiver = qSession.createReceiver(q);

        qConnection.start();
        Message msg = qReceiver.receive();

  // here send your message to third party application 
  //if your third party application is down 
        if(thirdpartyapp is down){
          //here you can raise an exception 
          //or just do nothing 
          // you're not sending acknowledgement here so the msg will 
           //remain in the queue
        }else{      
          msg.acknowledge();//here youre sending ack, so msg will be deleted
          qReceiver.close();
          qConnection.close();
        }

    } catch (JMSException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30266631

复制
相关文章

相似问题

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