1. 程式人生 > >談談Jedis的連線池技術

談談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();
        }
    }