58沈劍架構系列 一分鐘寫好連線池

2022-01-18 03:05:20 字數 2574 閱讀 3005

一、如何通過連線訪問下游

工程架構中有很多訪問下游的需求,下游包括但不限於服務/資料庫/快取,其通訊步驟是為:

(1)與下游建立乙個連線

(2)通過這個連線,收發請求

(3)互動結束,關閉連線,釋放資源

這個連線是什麼呢,通過連線怎麼呼叫下游介面?服務/資料庫/快取,官方會提供不同語言的driver、document、democode來教使用方建立連線與呼叫介面,以mongodb的c++官方driver api為例(偽**):

這個dbclientconnection就是乙個與mongodb的連線,官方driver通過它提供了若干api,讓使用者可以對mongodb進行連線,增刪查改,關閉的操作,從而實現不同的業務邏輯。

二、為什麼需要連線池

當併發量很低的時候,上述偽**沒有任何問題,但當服務單機qps達到幾百、幾千的時候,建立連線connect和銷毀連線close就會成為瓶頸,此時該如何優化?

結論也很簡單,服務啟動的時候,先建立好若干連線array[dbclientconnection],當有請求過來的時候,從array中取出乙個,執行下游操作,執行完再放回,從而避免反覆的建立和銷毀連線,以提公升效能。

這個對array[dbclientconnection]進行維護的資料結構,就是連線池。有了連線池之後,資料庫操作的偽**變為:

dbclientconnection* c = connectionpool::getconnection();

c->insert(「db.s」, bson(」shenjian」));

connectionpool::freeconnection(c);

三、連線池核心介面與實現

通過上面的討論,可以看到連線池connectionpool主要有三個核心介面:

(1)init:初始化好array[dbclientconnection],這個介面只在服務啟動時呼叫一次

(2)getconnection:請求每次需要訪問資料庫時,不是connect乙個連線,而是通過連線池的這個介面來拿

(3)freeconnection:請求每次訪問完資料庫時,不是close乙個連線,而是把這個連線放回連線池

連線池核心資料結構:

(1)連線陣列array dbclientconnection [n]

(2)互斥鎖陣列array lock[n]

連線池核心介面實現:

init(){

for i = 1 to n {

array dbclientconnection [i] = new();

array dbclientconnection [i]->connect();

array lock[i] = 0;

說明:把所有連線和互斥鎖初始化

getconnection()

for i = 1 to n {

if(array lock[i] == 0){

array lock[i] = 1;

return array dbclientconnection[i];

說明:找乙個可用的連線,鎖住,並返回連線

freeconnection(c)

for i = 1 to n {

if(array dbclientconnection [i] == c){

array lock[i] = 0;

說明:找到連線,把鎖釋放

可以發現,簡單的連線池管理並不是很複雜,基本原理即如上所述。

四、未盡事宜

上述偽**忽略了一些細節,在實現連線池中是需要考慮的:

(1)如果連線全部被占用,是返回失敗,還是讓上游等待

(2)需要實施連線可用性檢測

(3)為了讓呼叫方更友好,可能還需要包裝一層dao層,讓「連線」這個東西對呼叫方都是黑盒的

(4)通過freearray,connectionmap可以讓取連線和放回連線都達到o(1)時間複雜度

(5)可以通過hash實現id序列化

(6)負載均衡、故障轉移、服務自動擴容都可以在這一層實現

希望這一分鐘大家有收穫。

58沈劍架構系列 一分鐘了解負載均衡的一切

什麼是負載均衡 負載均衡 load balance 是分布式系統架構設計中必須考慮的因素之一,它通常是指,將請求 資料 均勻 分攤到多個操作單元上執行,負載均衡的關鍵在於 均勻 常見的負載均衡方案 常見網際網路分布式架構如上,分為客戶端層 反向 nginx層 站點層 服務層 資料層。可以看到,每乙個...

一分鐘sed入門(一分鐘系列)

1.簡介 sed是一種行編輯器,它一次處理一行內容。2.sed呼叫方式 sed options command file s sed options f scriptfile file s 第一種直接在命令列中執行,第二種把命令寫到了指令碼中,二者無本質區別。示例 1 列印hello.txt的內容 ...

一分鐘看懂資料湖架構

資料湖和資料倉儲兩者都廣泛應用於大資料儲存,但兩者之間概念不可互換。資料湖是儲存原始資料的池,目的仍沒有明確。資料倉儲儲存結構化的 已過濾 處理的資料,用於特定分析目的。兩種資料儲存架構經常被混淆,起始兩者之間差異大於共性。事實上,唯一共性都為了儲存海量資料。了解兩者 區別很重要,因為它們服務於不同...