JedisSentinelPool使用一組MasterListener線程做主從複制的主伺服器選舉工作。其父類Pool的close, destory方法用來關閉正真的redis用戶端連接配接池的對象。在JedisSentinelPool對象中重寫了destory方法内容是在關閉選舉線程之後,調用了父類destory方法;但是沒有重寫close方法,因而調用close方法不能關閉的掉MasterLinstener線程。Pool的另一個子類JedisPool則沒有對close,destory方法做任何變動。
JedisSentinelPool,JedisPool以及Pool之間的關系如下類圖:
檢視Pool中close和destory的源碼:
1
2
3
4
<code>@Override</code>
<code>public</code> <code>void</code> <code>close() {</code>
<code> </code><code>closeInternalPool();</code>
<code>}</code>
<code>public</code> <code>void</code> <code>destroy() {</code>
close方法實作自java.io.Closeable接口,Closeable是可以關閉的資料源或目标。調用 close 方法可釋放對象儲存的資源(如打開檔案)從這一點看是沒有問題的,如果是JDK1.7+的話,那更好了該接口繼承了AutoCloseable接口。對于JedisPool而言調用close方法和調用destory效果是一樣的,但JedisSentinelPool就不同了,建立JedisSentinelPool是啟動了MasterLinstener線程,是以得調用destory方法來完成JedisSentinelPool所持有的資源釋放,線程關閉。
JedisSentinelPool的destory方法:
5
6
7
<code> </code><code>for</code> <code>(MasterListener m : masterListeners) {</code>
<code> </code><code>m.shutdown();</code>
<code> </code><code>}</code>
<code> </code><code>super</code><code>.destroy();</code>
結論:如果要關閉的僅僅是Pool(Reids用戶端連接配接池)則調用close,而要關閉主從複制中的主機檢測即徹底關閉JedisSentinelPool則要調用destory方法。
意外想當然的調用close方法,并沒能關閉MasterLinstener線程,并且MasterLinstener線程沒有起個好名字,排查是看到的名字叫Thread-xx (xx是數字),這樣很不友善排錯。!!!是以啟動線程起個好名字真的非常必要,這将對排錯,診斷,系統監控有莫大的幫助。
本文轉自 secondriver 51CTO部落格,原文連結:http://blog.51cto.com/aiilive/1682260,如需轉載請自行聯系原作者