美文网首页
系统时间变化导致ActiveMQ消费者僵死的问题

系统时间变化导致ActiveMQ消费者僵死的问题

作者: MisterCH | 来源:发表于2017-02-27 17:07 被阅读206次

由于环境中有部分服务器每天都会定时重新设置系统时间,ActiveMQ的连接常常出现僵死的情况。现象为Agent不再输出日志,根据现有日志判断线程卡在consumer.receive(60000)这一个语句上。今天下定决心研究了一下源码。

相关资料:http://m.blog.csdn.net/article/details?id=53501723

Agent在调用consumer.receive(60000)方法时,MQ内部的操作有一层是这样的(ActiveMQMessageConsumer.dequeue方法)

if  ( timeout  > 0) { 
    deadline  = System. currentTimeMillis () + timeout ; 
} 
while  ( true ) { 
     MessageDispatch md  = unconsumedMessages .dequeue( timeout ); 
     if  ( md  == null ) { 
        if  ( timeout  > 0 && ! unconsumedMessages .isClosed()) { 
           timeout  = Math. max ( deadline  - System. currentTimeMillis (), 0); 
………… 

当系统时间变化时(往前调整), System. currentTimeMillis 取到的时间会变小,最后一行的timeout会变大,导致等待时间增加,而且在 unconsumedMessages .dequeue( timeout ); 方法中,调用了如下的命令

   while  ( timeout  != 0 && ! closed  && ( list .isEmpty() || ! running )) { 
        if  ( timeout  == -1) { 
             mutex .wait(); 
        } else  { 
              mutex .wait( timeout ); 
               break ; 
        } 
   } 

mutex.wait(timeout),timeout为上一层中变大后的值,从而导致线程僵死,且不再接收消息,直到系统时间回复到(变化前的时间+60s)以后才能恢复正常。

解决方法是不在consumer.receive(timeout)中使用>0的timeout,由自己封装一层,每次调用consumer.receive(0),而后加一层逻辑判断系统时间是否有变化。

更进一步的解决方法是去官方提个bug。。。。。嗯,明天搞。。

相关文章

网友评论

      本文标题:系统时间变化导致ActiveMQ消费者僵死的问题

      本文链接:https://www.haomeiwen.com/subject/zqozwttx.html