xmemcached 1.2.6.2紧急发布(升级到1.2.6.1的朋友注意)

    xiaoxiao2024-01-08  141

    今年在阅读某个项目源码的时候看到DelayQueue的使用, xmemcached 1.2.6.1的重连任务也是采用DelayQueue管理,ReconnectRequest实现Delayed接口,我突然想起去review下xmc的源码,发现一个严重的BUG,原始代码如下: public   final   class  ReconnectRequest  implements  Delayed {        public   long  getDelay(TimeUnit unit) {          return   nextReconnectTimestamp  -  System.currentTimeMillis();     } }     getDelay返回该任务还剩下多少时间可以被执行,将下次执行的时间戳减去当前时间即可,问题在于这里返回的是毫秒,而没有调用getDelay传入的TimeUnit做转换,在DelayQueue内部其实是用纳秒做单位交给Condition对象去等待    for  (;;) {                 E first  =  q.peek();                  if  (first  ==   null ) {                     available.await();                 }  else  {                      long  delay  =   first.getDelay(TimeUnit.NANOSECONDS);                      if  (delay  >   0 ) {                          long  tl  =  available.awaitNanos(delay);                     }  else  {                         E x  =  q.poll();                          assert  x  !=   null ;                          if  (q.size()  !=   0 )                             available.signalAll();  //  wake up other takers                          return  x;                     }                 }             }         最终导致的问题是, awaitNanos很快返回( awaitNanos接受的是纳秒,这里却传入毫秒) ,循环执行发现重新计算的delay仍然大于0,循环等到getDelay返回的越来越小直到0才执行相应的Task,,造成的现象是在重连的时候cpu占用率很高。      单元测试的时候没有发现这个问题,主要是因为功能正常,没有关注资源消耗情况,因此惭愧地忽略了。       解决的办法很简单,修改getDelay方法即可:      public   long  getDelay(TimeUnit unit) {          return  unit.convert(                 nextReconnectTimestamp  -  System.currentTimeMillis(),                 TimeUnit.MILLISECONDS);     }

          这个BUG比较严重,已经升级1.2.6.1的朋友建议马上升级到1.2.6.2,使用maven的朋友只要修改版本即可,没有使用maven的请到这里下载。

    文章转自庄周梦蝶  ,原文发布时间 2010-10-22

    相关资源:xmemcached-1.2.6.2
    最新回复(0)