設計乙個可靠的連線池

2022-01-13 12:02:37 字數 2396 閱讀 3929

在應用中連線池的使用非常普遍,如訪問資料庫,redis等等網路產品的client都整合了連線池機制;由於最近在編寫微服務閘道器因此涉及到連線池的編寫,在這裡分享一下實現乙個可靠連線池的心得。其實編寫乙個連線池並不因難,基礎的stack結構就能滿足需要;但在設計的時候有些情況是需要考慮的,怎樣使連線池的效益最大化,特別是如何設計連線池的最大負載,當超過最大負載後應該怎麼做這些問題都衡量乙個連線池好壞的標準。接下來通過**的方式一步一步地實現它。

public

class connectionpoolwhere t : idisposable, new

()

return

item;

}public

void

push(t item)

}

以上是乙個最簡單物件池,當然這個物件池是不能真的投入生產,只是大概了解基礎原理;因為它是無限量增長的物件池,不過用來做物件池免強還是可以的,用在連線池上那就不太可行了,畢竟大量的連線不僅增加自己的損耗還增加了對端的損耗。

public

class connectionpoolwhere t : idisposable, new

()

private concurrentstackmpool = new concurrentstack();

private

intmmaxcount;

private

intmcount;

public

t pop()

item = new

t();

}return

item;

}public

void

push(t item)

}

以上增加了最大數限制,但在使用上就要面對乙個問題,當池負載滿了返回為空的時候程式又要怎樣處理呢?直接拋異常?自旋或sleep指定次數後還是獲取為空再報異常?對於呼叫者來說最不想看到的肯是異常,就算延時能處理也相對是一件不錯的方法;但當在滿負載的情況大量的執行緒自旋或sleep又只會讓系統變得更糟糕!所以以上兩種方式並不算是乙個好的解決方法。

如果請求者要等待使用自旋或sleep基本上是不可行,這種方法容易損耗cpu資源;接下來引入基於事件驅動的方法模式,聽上去是不是很高大上,其實設計方式比較簡單就是在push引入乙個事件通知機制,讓後面等待的請求進行處理;這樣就不用通過自旋或sleep來完成這個功能。一說到事件驅動相信很多朋友感覺一下子變成了非常複雜,但.net core提供給我們乙個好東西async/await語法糖輕易解決這一問題。

public

class connectionpoolwhere t : idisposable, new

()

private

int mwaitqueuelength = 1000

;

private stackmpool = new stack();

private queue> mwaitqueue = new queue>();

private

intmmaxcount;

private

intmcount;

private

object mlockpool = new

object

();

public taskpop()

else

else

else}}

return

result.task;}}

public

void

push(t item)

else}}

}

在物件池中引入了乙個佇列,當負載滿的時候請求會扔到佇列中,當物件回歸後會檢測佇列並觸發請求的狀態機**執行。注意:一定要通過執行緒隔離這個執行,畢竟這**還在乙個鎖的**塊裡,如果不用執行緒隔離有能可能會導致下一次其它呼叫進來時產生死鎖的情況。加入了事件驅動使用**如下:

var item = await

pool.pop();

if(item==null

)

throw

system busy

else

run item

池在負載的時候有增長,那在空閒的時候自然也應該有縮減的設計才算合理,同樣這個縮減也可以在push中設計一下,**就留給大家了,簡單的方法是獲取當前pool的pop的併發量,如果併發量少於當前池中的物件數量,那push的時候就不是回歸到池裡,而是釋放掉了(不過這個方法並不算太好)。

2020 04 27 設計乙個連線池

此答案來自群員,感謝群員支援。有些題目,表面叫你設計乙個連線池,背地裡想考你連線池的原理。面試官你好,如果讓我設計乙個連線池,首先我會設計乙個 核心執行緒數 用來常駐記憶體中,迅速響應任務進行。再設計乙個 最大可擴充套件執行緒數 用來當任務增多的時候最多擴充套件執行緒的數量,當達到最大執行緒數的時候...

如何實現乙個連線池?

目錄前言 什麼是連線池?為什麼需要連線池?怎樣做乙個連線池?高階連線池 推薦原始碼 2w1h 是技術領域中一種非常有效的思考和學習方式,即what why和how 堅持 2w1h 可以快速提公升我們的深度思考能力。今天我們通過 2w1h 方式來討論 連線池 什麼是連線池 what 為什麼需要連線池 ...

實現乙個redis連線池

jedis連線引數設定 redis伺服器ip redis.ip 169.254.130.122 redis伺服器端口號 redis.port 6379 redis訪問密碼 redis.password test123 與伺服器建立連線的超時時間 redis.timeout 3000 jedis池引數...