2012-01-08 86 views
3

我有一个接收来自队列消息的客户端。我目前有一个执行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) {} 
+0

如果数据库关闭,为什么不等到启动前再尝试继续。这样就没有必要重播消息 – 2012-01-08 11:05:36

+0

你的意思是阻止直到数据库启动?我不确定这是否可以......除非我误解你的评论。 – gkinu 2012-01-08 14:23:02

+0

如果你阻塞,直到数据库启动会发生什么?该线程是否有更重要的事情要做? ;)如果是这样,我会在另一个线程,会话或连接中运行更重要的事情。 – 2012-01-08 14:25:46

回答

0

经过一些研究,我偶然发现了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) {} 
0

我认为标准的行为已经做你想要什么:如果消息代理是使用相同的数据库,并且数据库不可用,也不会接受消息,因此客户端将对其进行后台处理,直到消息代理再次准备就绪。

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

+0

谢谢。我想我的问题是如何以及在哪里配置activeMQ重新发送未确认的消息,而不是从客户端初始化重新发送请求。我怎样才能做到这一点? – gkinu 2012-01-08 14:20:54

相关问题