【问题标题】:Can I Send a Message Request Directly to a Queue?我可以直接向队列发送消息请求吗?
【发布时间】:2012-02-05 07:06:33
【问题描述】:

我有一个从队列接收消息的客户端。我目前有一个实现onMessage()MessageListener

收到消息后,将对其进行进一步处理,然后通过onMessage() 方法将其保存到数据库中;客户端然后确认消息接收。

只要数据库正常,就没有问题。但是如果数据库关闭,客户端将不会确认。

为了解决这个问题,我希望客户端按预定时间间隔向队列发送任何未确认消息的预定请求。

事实上,我这样做的唯一方法是重新启动不理想的客户端。有没有办法触发队列重新发送未确认的消息而无需重新启动?

我在onMessage() 有什么:

//code to connect to  queue
try {
if (DB is available){
        //process message
        //save required details to DB
        msg.acknowledge();
    }
    else{
        //schedule to request same message later from queue
    }
} catch (Exception e) {}

【问题讨论】:

  • 如果数据库已关闭,为什么不等到它启动后再尝试继续。这样就不需要重播消息
  • 你的意思是阻塞直到数据库启动?我不确定这是否可以……除非我误解了您的评论。
  • 如果在数据库启动之前一直阻塞会发生什么?那个线程有更重要的事情要做吗? ;) 如果是这样,我会让更重要的事情在另一个线程、会话或连接中运行。

标签: java queue jms activemq


【解决方案1】:

我认为标准行为已经在做你想做的事情:如果消息代理正在使用相同的数据库并且数据库不可用,它将不接受消息,因此客户端将假脱机直到消息代理准备好再次。

如果它们不共享同一个数据库并且消息代理已打开,它将假脱机消息并在onMessage 抛出异常时重试。 消息代理将根据其可配置的策略尝试重新发送。

【讨论】:

  • 谢谢。我想我的问题是如何以及在何处配置 activeMQ 以重新发送未确认的消息,而不是初始化来自客户端的重新发送请求。我该怎么做?
【解决方案2】:

经过更多研究,我偶然发现了 session.recover(),我可以用它来触发重新投递。我已经看到有 RedeliveryPolicy 类,我可以使用它来设置消息重新发送选项。现在我的代码看起来像:

ConnectionFactory factory = new ActiveMQConnectionFactory(url);
RedeliveryPolicy policy = new RedeliveryPolicy();
policy.setBackOffMultiplier((short) 2);
policy.setRedeliveryDelay(30000);
policy.setInitialRedeliveryDelay(60000);
policy.setUseExponentialBackOff(true);
((ActiveMQConnectionFactory)factory).setRedeliveryPolicy(policy);

final Session session = connection.createSession(false,
                Session.CLIENT_ACKNOWLEDGE);
...
...
...
..


//inside onMessage()
try {
    if (DB is available){
        //process message
        //save required details to DB
        msg.acknowledge();
    }
    else{
        session.recover();
    }
    } catch (Exception e) {}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-22
    • 2018-12-16
    • 1970-01-01
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2017-07-18
    相关资源
    最近更新 更多