先做點準備工作:
上面這個類,用來封裝服務端的基本資訊,主機名+端口号,連接配接時需要用到。
這是對TTransport的封裝,主要增加了一些輔助資訊,直接看代碼注釋即可。
下面才是連接配接池的主要内容:
主要思路:
1.構造器裡,傳入 連接配接池大小,最小連接配接數,連接配接最大空閑時間,空間連接配接檢測時間間隔,服務端清單等基本資訊
2.然後調用init方法進行初始化,初始化時把pool[]數組填滿,不過在填充的時候,要根據minsize決定激活多少連接配接(換句話講,連接配接執行個體都都建好了,隻是連不連的問題),另外初始化的時候,還要考慮到某個伺服器當機的可能,如果服務端挂了,将對應的執行個體設定為isDead=true的狀态
3.新開一個線程定時檢查是否有空閑連接配接,如果空閑時間太長,主動斷開,以節省開銷。
4.get()方法從數組中撈一個可用的連接配接出來,取的時候要考慮到喚醒"沉睡"連接配接的情況,即如果目前池中隻有2個活動連接配接,這時又來了請求,沒有活動連接配接了,要從池中把斷開的連接配接叫醒一個。
測試:
輸出:
****************************
開始檢測空閑連接配接...
目前活動連接配接數:1
Thread1 => hashCode:919192718,localhost:9001,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:09:59
Thread0 => hashCode:1510835162,localhost:9000,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:09:59
localhost:1002 java.net.ConnectException: Connection refused
Thread2 => hashCode:1466719669,localhost:9000,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:00
Thread3 => hashCode:2080503518,localhost:9001,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:00
Thread4 => hashCode:411724643,localhost:9000,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:00
--------------
Thread0 done.
poolsize:15,minSize:1,maxIdleSecond:5,checkInvervalSecond:10,active:5,busy:3,dead:2
Thread1 done.
Thread2 done.
poolsize:15,minSize:1,maxIdleSecond:5,checkInvervalSecond:10,active:5,busy:2,dead:2
Thread3 done.
poolsize:15,minSize:1,maxIdleSecond:5,checkInvervalSecond:10,active:5,busy:1,dead:2
Thread4 done.
poolsize:15,minSize:1,maxIdleSecond:5,checkInvervalSecond:10,active:5,busy:0,dead:2
1510835162,localhost:9000 超過空閑時間閥值被斷開!
919192718,localhost:9001 超過空閑時間閥值被斷開!
1466719669,localhost:9000 超過空閑時間閥值被斷開!
2080503518,localhost:9001 超過空閑時間閥值被斷開!
Thread0 => hashCode:411724643,localhost:9000,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:31
Thread1 => hashCode:1510835162,localhost:9000,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:31
Thread2 => hashCode:919192718,localhost:9001,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:31
Thread3 => hashCode:1466719669,localhost:9000,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:31
Thread4 => hashCode:2080503518,localhost:9001,isBusy:true,isDead:false,isOpen:true,isAvailable:false,lastUseTime:2015-09-27 16:10:31
poolsize:15,minSize:1,maxIdleSecond:5,checkInvervalSecond:10,active:5,busy:4,dead:2
輸入任意鍵退出...
q
連接配接池被銷毀!
***********************
注意上面高亮顔色的部分,2080503518 連接配接建立後,後來被check方法主動檢測到空閑斷開,然後第二輪調用時,又重新激活。411724643 則幸免于難,一直戰鬥到最後。另外由于故意寫錯了一個server位址,池中始終有二個dead的執行個體。
值得改進的地方:
主要是公平性的問題,在初始化的時候,如果伺服器有3台,而指定的連接配接池大小為4,目前的做法是,用4對3取模,是以第1、4個連接配接執行個體都是連接配接到伺服器1,get取可用連接配接的時候也有類似情況,是按pool數組從前向後周遊的,撈到第1個可用的連接配接就完事了,這樣永遠是排在List前面的伺服器壓力會大一些,這樣有點不太符合負載"均衡"的本意。
不過,這個問題也很好解決,有一個很簡單有效的技巧,實際應用中,伺服器清單是從zk上取回來的,取回來後,先對數組做随機排序,這樣整體看來下,多個連接配接池總體的連接配接分布情況就比較平均了。