談談Jedis的連線池技術
其實這篇文章的題目,應該叫談談Apache common pool的連線池技術
這篇部落格,就不怎麼分析原始碼了,咱們儘量把觀察的層次提高一下,主要分析流程。
下圖是JedisPool裡面用到的一些類(有些類我省略了,例如closeable)
PooledObjectFactory<T>,是一個泛型介面,裡面有makeObjcet,destroyObject,validateObject等方法,就是生成一個物件,銷燬一個物件,判定是否合法等的
PooledObject 是對基本物件的一個包裝,包含基本物件的建立時間,狀態等等
GenericObjectPool 裡面包含了borrowObject與returnObject等方法
我們一般的從pool中取物件呼叫的是JedisPool的getResource方法
時序圖如下:
在GenericObjectPool中有下面這個成員變數:
private final LinkedBlockingDeque<PooledObject<T>> idleObjects;
在上面時序圖裡第三步create前,會先在idleObjects裡面找(idleObjects.pollFirst()),如果沒有物件(這是一個佇列),才去create,否則就直接返回idleobjects裡面的。
釋放連線,我們一般直接呼叫jedis的close方法。
如下圖
最後那個LinkedBlockingDeque就是idleObjects。
當然,我上面的時序圖,是我省略了很多很多的,但是主體就是上面的。
另外,pool的原始碼我自己看的也比較粗,如果文中有什麼錯誤,還請各位大神一定指出。
有一個問題,如果我給pool設定的最少連線是20
那麼這20個連線時連線池一開始就迴圈產生的,還是後面借一個,才生出一個?
換句話說就是勤生產還是懶生產。
答案是勤生產(準確的說是,自pool載入後timeBetweenEvictionRunsMillis毫秒開始生產這個連線物件,timeBetweenEvictionRunsMillis模式是30000毫秒)
timeBetweenEvictionRunsMillis毫秒秒檢查一次連線池中空閒的連線,把空閒時間超過minEvictableIdleTimeMillis毫秒的連線斷開,直到連線池中的連線數到minIdle為止
//GenericObjectPool.java void ensureMinIdle() throws Exception { ensureIdle(getMinIdle(), true); } private void ensureIdle(int idleCount, boolean always) throws Exception { if (idleCount < 1 || isClosed() || (!always && !idleObjects.hasTakeWaiters())) { return; } while (idleObjects.size() < idleCount) { PooledObject<T> p = create(); if (p == null) { // Can't create objects, no reason to think another call to // create will work. Give up. break; } if (getLifo()) { idleObjects.addFirst(p); } else { idleObjects.addLast(p); } } if (isClosed()) { // Pool closed while object was being added to idle objects. // Make sure the returned object is destroyed rather than left // in the idle object pool (which would effectively be a leak) clear(); } }