2012-01-08 5 views
3

У меня есть клиент, который получает сообщения из очереди. В настоящее время у меня есть MessageListener, который реализует onMessage().Могу ли я отправить сообщение прямо в очередь?

После получения сообщения он обрабатывается далее, затем сохраняется в базе данных по методу 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

Если база данных не работает, почему бы не подождать, пока она не появится, прежде чем пытаться продолжить. Таким образом, нет необходимости переписывать сообщения –

+0

Вы имеете в виду блок до тех пор, пока БД не встанет? Я не уверен, что все в порядке ... если я не понял ваш комментарий. – gkinu

+0

Что произойдет, если вы заблокируете базу данных? Есть ли в этой теме что-то более важное? ;) Если это произойдет, у меня будет более важная работа в другом потоке, сеансе или соединении. –

ответ

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

Смежные вопросы