如何實現乙個連線池?

2021-10-10 13:38:51 字數 2988 閱讀 4471

目錄前言

什麼是連線池?

為什麼需要連線池?

怎樣做乙個連線池?

高階連線池

推薦原始碼

【2w1h】是技術領域中一種非常有效的思考和學習方式,即what、why和how;堅持【2w1h】,可以快速提公升我們的深度思考能力。

今天我們通過【2w1h】方式來討論「連線池」:什麼是連線池(what)?為什麼需要連線池(why)?怎樣做乙個連線池(how)?

深入思考連線池的本質,但不要思考的過於複雜!

「池」是一種非常形象化的描述,它是一種容器,做儲存之用;在程式設計中我們往往使用陣列、鍊錶、佇列、map來表達。

「連線」是網路中用於傳輸資料的通道;「連線」才是我們要真正去使用的物件,而「池」是用來管理「多個連線」的一種方式。

如果沒有用「池」來統一管理「連線」,「連線」將散布在程式各處;那為了使用方便,我們往往會在使用時建立連線,使用完畢後,就關閉連線。所以「連線池」給我們提供了使用「連線」的方便。

同時,池是做儲存之用的,所以「連線池」中的「連線」肯定是已經建立好的長連線,比如tcp連線、websocket連線等,即取即用,用完放回。如果沒有真正理解「連線池」的本質,在面試中可能會出現「http連線池」的笑話!

根據下游型別,我們常見有資料庫連線池、快取連線池、服務連線池,如下圖所示:

圖一 資料庫連線池

圖二 快取連線池

圖三 服務連線池

在程式設計中,我們還經常會碰到程序池、執行緒池、協程池、記憶體池、物件池等。

除了連線池能非常方便的對連線進行管理外,一句話,在高吞吐時連線池大大提高了資料傳輸的效率。

從兩個方面說:

1、避免反覆的三次握手和四次握手

長連線的建立需要進行三次握手,而連線的釋放需要進行四次握手,這是發生在系統層面的兩個動作,對於單條連線來說耗時微乎其微,但在高吞吐場景時,耗時則不能忽略。

所以連線池的即取即用和用完放回的特性,避免了大量三次握手和四次握手的無效耗時,節省了系統資源。

2、 增加並行車道,實現全雙工並行

資料通訊包括單工、半雙工和全雙工。單工通訊如下圖,資料只能從a到b,不符合訪問下游服務的場景。

圖四 單工通訊

半雙工通訊如下圖,資料可以從a到b,也可從b到a,但是同一時刻只能乙個方向上進行資料傳輸,通道利用率是50%。

圖五 半雙工通訊

全雙工通訊如下圖,可同時存在從a到b和從b到a的資料傳輸,通道的利用率是100%。長連線就是全雙工通訊。

圖六 全雙工通訊

在io密集型的網際網路應用中,一條全雙工通訊通道仍然無法滿足資料吞吐的需求時,該如何解決?

在網際網路效能測試指標中有這樣乙個公式:

qps(吞吐量) = 併發數 / 平均響應時間
在平均響應時間不變的情況下,適度增加併發數可以提公升吞吐量;所以採用多條全雙工通訊的方式可以在一定程度上(平均響應時間沒有大幅增加)提高吞吐量,而連線池則就最好的實現方式。

總結一下:為什麼需要連線池?

(1)方便管理連線;

(2)避免反覆三次握手和四次握手;

(3)更好地實現全雙工並行。

實現乙個連線池,最關鍵的是均衡和保活,如下圖所示:

圖七 連線池實現原理

該連線池的「池」通過佇列資料結構進行實現,佇列先進先出的特性保證了使用連線的均衡性,每一條連線都可以均勻的被使用到。

連線池對外提供get()和free()兩個apiget()用於從隊首「出隊」獲取一條可用連線,free()用於將使用完的連線從對尾「入隊」釋放到佇列中

業務**在低峰時會降低get()動作,所以連線池中的連線在長時間不用時會導致失效,此時保活執行緒在監測到get()的使用頻率較低時,會模擬業務程式呼叫get()獲取連線後傳送心跳包,然後再通過free()將被保活的連線放回佇列中,達到連線池中所有連線保活的目的。

在充分理解上述內容後,可以了解高階連線池的擴充套件知識!

高階連線池通常應用在微服務系統中,如下圖:連線池連線下游多個節點。

圖八 高階連線池

高階連線池具備這樣幾個特性:

2、 高可擴充套件:下游增加乙個server節點時,連線池會發現並建立到新server節點的連線,供client訪問;

3、 負載均衡:連線池會根據下游server的服務能力的高低分配資料請求;

4、 中介軟體:當下游server是類mysql資料庫並分片時,連線池會將請求打在相應的資料節點上,並對資料進行聚合。

redispool:

rabbitmq_connet_pool:

實現乙個redis連線池

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

2020 04 27 設計乙個連線池

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

設計乙個可靠的連線池

在應用中連線池的使用非常普遍,如訪問資料庫,redis等等網路產品的client都整合了連線池機制 由於最近在編寫微服務閘道器因此涉及到連線池的編寫,在這裡分享一下實現乙個可靠連線池的心得。其實編寫乙個連線池並不因難,基礎的stack結構就能滿足需要 但在設計的時候有些情況是需要考慮的,怎樣使連線池...