莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          XMemcached的一個嚴重BUG

          Posted on 2009-09-27 23:29 dennis 閱讀(3394) 評論(6)  編輯  收藏 所屬分類: javamy open-source
              泰山在線的周利朋友對xmemcached做了很多測試,他發現了一個比較嚴重的BUG,在linux平臺的重連機制有時候會失效。表現的現象是這樣,正常連接上memcached之后,kill掉其中的一臺memcched server,xmemcached會開始自動重連這臺server直到連接成功,然而事情沒有像預想的那樣,現象是有時候可以重連成功,有時候卻沒有,如果設置了connectionPoolSize,有時候建立的連接數達到connectionPoolSize,有時候卻沒有。他還向我描述了那時候的netstat觀察到的網絡情況,有比較多CLOSE_WAIT存在,這個顯然是由于memcached主動斷開,xmemcached被動進入CLOSE_WAIT,但是沒有發送FIN的情況,如果有發送FIN那應該進入LAST_ACK而不是停留在CLOSE_WAIT。因此反應的第一個問題是xmemcached沒有在接到memcached斷開之后主動關閉socket發送FIN。檢查代碼發現其實是有這個邏輯,但是nio的channel關閉有個隱蔽的問題,就是在SelectionKey.cancel之后還需要調用select才能真正地關閉socket,這里會有個延遲,另外,為了防止CLOSE_WAIT現象的再次發生,設置SO_LINGER選項強制關閉也是必須的。做了這兩個修改后,build了一個臨時版本請周利朋友幫忙測試,重連失敗的情況有所減輕,但是仍然會發生。因此根本的問題不在于CLOSE_WAIT的處理上,通過檢查代碼發現了下面這段代碼:
          if(!future.isDone()&&!future.get(DEFAULT_CONNECTION_TIMEOUT,TimeUnit.MILLISECONDS){
            
          }
          else{
             connected
          =true;
          }

             可能你已經發現問題在哪。這段代碼的意圖是通過future.get阻塞等待連接成功或者失敗,如果失敗做一些處理,如果成功將connected設置為true。這里判斷失敗有兩個條件,future.isDone為false,并且future.get也返回false才認為失敗,問題恰恰出在這里,因為future.isDone可能在連接的失敗的情況下返回true,而這段邏輯將這種情況誤判為連接成功,導致重試的請求被取消。修改很簡單,將future.isDone這個條件去掉即可。
              回想起來,我也忘了當初為什么加上這個條件,這里感謝下周利的幫助,并且向使用xmemcached的朋友們提個醒。這個問題在win32平臺上不會出現(比較詭異,估計跟并發有關),在linux平臺出現的幾率比較大,預計在10月份發布的1.2.0-stable中修正,這個stable版主要工作是修復BUG。歡迎更多朋友反饋問題和BUG,我將及時修復和反饋。


          評論

          # re: XMemcached的一個嚴重BUG  回復  更多評論   

          2009-09-27 23:50 by 周利
          dennis這么快速、負責的解決了問題,我很敬佩!

          # re: XMemcached的一個嚴重BUG  回復  更多評論   

          2009-09-28 08:52 by bsli123@hotmail.com
          希望XMemcached 能保持簡潔實用的功能,不要引入太多花哨的東西,正像Memcached一樣簡潔

          # re: XMemcached的一個嚴重BUG  回復  更多評論   

          2009-09-28 09:53 by dennis
          @bsli123@hotmail.com
          謝謝你的建議。xmemcached發展到現在,很多功能其實都是被動添加的,比如連接池是在用戶發現高并發下單連接的nio很容易超時,比如kestrel的支持是有用戶拿xmemcached去連接kestrel,所以就xmemcached本身不會主動去添加一些花哨的東西,一個簡單的類庫也不能承擔太多責任。

          # re: XMemcached的一個嚴重BUG  回復  更多評論   

          2009-09-28 16:13 by bsli123@hotmail.com
          向你請教一個問題,memecache緩存單個對象大小可有什么限制?

          # re: XMemcached的一個嚴重BUG  回復  更多評論   

          2009-09-28 16:48 by dennis
          @bsli123@hotmail.com
          允許的最大大小是1M。

          # re: XMemcached的一個嚴重BUG  回復  更多評論   

          2016-05-17 11:16 by wei.huang
          非常感謝作者提供這么好的工具,在使用的過程中遇到一些問題?
          1、使用連接池后,當一個節點斷開連接后會一直嘗試連接并報出connect refused 異常?是因為有重試機制嗎?
          2、動態添加節點addserver時當節點服務通信異常也會拋出connect refused 異常,并一直重試?

          麻煩作者提供解決思路,非常感謝
          主站蜘蛛池模板: 宁德市| 黑龙江省| 大城县| 寿宁县| 和林格尔县| 巢湖市| 高台县| 安福县| 奉新县| 比如县| 晋中市| 云梦县| 宝丰县| 武陟县| 佛山市| 荆门市| 嘉禾县| 连城县| 出国| 万盛区| 滨州市| 虎林市| 满城县| 瓮安县| 五河县| 东乌| 南宁市| 巴彦县| 吉木萨尔县| 辛集市| 恩平市| 和田县| 拉孜县| 逊克县| 荆门市| 安龙县| 贵德县| 赣榆县| 虞城县| 桃江县| 遂宁市|