克里斯汀·圖頓吉安(christine tutunjian)的照片
>連接池是一種創建和管理應用程序可以使用的數據庫連接池的機制。該概念對于管理與數據庫的連接很重要,目的是優化資源使用并改善經常與數據庫相互作用的應用程序的性能。
。
>不是每次需要的新連接(在時間和資源方面價格昂貴),而是允許應用程序允許應用程序借用/使用現有連接并在使用它們完成后將其返回池。這就是為什么它被稱為連接池。
>
為什么連接池很重要?
>重要的問題是,為什么連接輪詢很重要?為什么不只是建立1個連接以交替使用。讓我們討論1 bot 1為什么連接池很重要。
更好的性能
>打開與數據庫的新連接可能需要時間,因為它經歷了多個過程,例如身份驗證,網絡設置等。使用連接池,應用程序可以避免此過程,因為如果需要時已經可以使用連接。
資源節省
沒有池,如果應用程序收到100個請求,則應用程序將創建100個新連接。這可能會負擔數據庫服務器的負擔,該數據庫服務器總是忙于執行初始化過程。連接池可以限制同時使用的連接數量,這使數據庫服務器負載穩定。
>
可伸縮性
當應用程序擴展時,連接池幫助應用程序可以很好地管理負載。通過良好的連接池設置,我們可以同時處理大量請求,并確保應用程序保持響應迅速。
負載配置
可以根據需要配置連接池。因此,它可以防止應用程序泛濫到數據庫的連接。
>
如何工作?
>現在我們了解了為什么使用連接池很重要,我們現在將討論連接輪詢的工作原理。
池初始化
>第一次運行應用程序時,它可以與數據庫建立一定數量的連接(例如,10個連接)。此數字稱為
池大小
。此連接將閑置等待使用。
連接用法
應用程序需要與數據庫的連接連接時,它不再創建新連接,而是從池中請求連接。如果池中有連接可用,則將分配給應用程序。如果沒有可用的連接,則該應用程序可能必須等到釋放連接并在另一個進程使用后返回池。
還原連接
>應用程序使用連接完成,它將無法關閉連接。相反,連接將返回到池中,以通過下一個請求再次使用。
>
連接池中的共同主要參數
>以下是創建連接池時通常使用的一些主要參數。我將嘗試詳細解釋,然后進行類比,這些類比可以幫助我們更好地理解每個上下文。
> 游泳池尺寸
我們可以確定
池大小
中提供的連接數量。如果使用了所有連接,則在使用該連接請求時,將排隊等待可用連接,否則隊列已滿,它將失敗。
例如,如果我們將最大池大小設置為10,則應用程序只能使用10個活動連接。如果提出第11個請求,則此請求將等待已經使用的池的連接。類比是這樣的:
想象一下有一個停車場,如果所有插槽都已滿,則想要輸入>(連接請求)
必須等到另一輛車出來
>(空閑連接)。
- 如果我們想容納更多的汽車,我們必須建造更多的停車位(增加
,以便我們可以容納更多的汽車。但是維護成本增加(>服務器資源)。> 最小連接 - >最小池尺寸5,則池將確保始終有5個空閑連接。即使沒有主動請求,池仍然可以確保這5個連接開放,以減少請求進來的連接打開時間。 >這對于預測不穩定的負載很有用,例如,突然間,我們的應用程序獲得了很多請求,并且可以使用連接,而無需打開新連接。類比是這樣的:
最小連接是第一次運行應用程序時將創建的連接數量。這是一個連接,即使沒有請求,也將始終處于待機狀態。例如,如果我們設置
想象一家餐廳有10個椅子,故意在飯廳安排,而是存放在倉庫中。但是,當有很多訪客時,我們需要額外的椅子,我們不需要很長時間在商店購買。但是,只需要去倉庫,拿起所需的10個椅子即可。
空閑連接
閑置連接是未使用的連接數量,但仍在池中打開,也可以稱為“空閑連接”。此參數通常由以下方式設置:
最大空閑時間
:關閉之前保持閑置連接的時間。
>最大空閑連接
:允許保留在池中的空閑連接的數量。
例如,如果我們設置
> maxidleconnections = 5,
池將保持最大5個空閑連接。如果有更多空閑連接,它將關閉。如果在一定時間內沒有新的請求(例如10分鐘),則可以刪除這些空閑連接以節省資源。類比是這樣的:
- 在超市,有5個收銀員,有3個收銀員正在為買家提供服務(主動連接),有2個出納員在沒有買家隊列(閑置連接)的情況下待命,只要買家來。 超市有一條規則:“如果收銀員在沒有客戶的情況下待命30分鐘,那么他們可以回家。”這30分鐘是空閑的時間。
- 暫停 >我們可以設置應用程序在池失敗之前從池中等待連接的最長時間(錯誤)。這樣做是為了防止應用程序忙或飽滿的話,應用程序等待了太長時間以無法獲得池的可用連接。這對于防止應用程序等待時間太長是有用的,該連接會導致應用程序“凍結”,在此更好地給用戶出現錯誤,以便它可以向用戶提供信息,以便再次嘗試而不是結果在凍結請求中。
例如,如果我們設置5秒鐘的超時,則如果請求無法連接,則等待5秒后會收到錯誤。要記住的要點是,太短的超時會導致請求太快失敗,并且超時時間太長意味著請求將懸掛太長時間。類比是這樣的:
>我們正在排隊在餐廳購買(請求),但我們等不及隊列(超時限制)。我們決定離開餐廳(返回錯誤)。>
- 最大壽命
- 之前可以持續多長時間,即使連接處于活動狀態。通常用于避免舊的連接問題或更新配置,以確保連接保持新鮮和可靠。
>生命周期確定連接可以在池重置或關閉
例如,如果我們設置
最大壽命
20分鐘,則使用20分鐘的任何連接都將
從池中刪除,并將被新的連接取代將創建的連接。
>這很重要,因為有時某些數據庫服務器對舊連接的時間限制有時間限制,這可以防止過時連接**問題。類比是這樣的:
>辦公室每班有3名保安人員。每個官員最多工作8小時(最大壽命)
>
8小時后,即使前5名軍官仍然處于良好狀態,也沒有問題,而且工作正常運行。但這可以防止官員在檢查來訪者時疲倦和失去專心(請求)。
執行 >現在我們將嘗試使用golang實現連接池。注意以下代碼:
package main import ( "database/sql" "fmt" "log" "time" _ "github.com/go-sql-driver/mysql" ) func main() { dsn := "username:password@tcp(127.0.0.1:3306)/dbname?parsetime=true" db, err := sql.open("mysql", dsn) if err != nil { log.fatalf("failed to open connection to database: %v", err) } defer db.close() db.setmaxopenconns(10) db.setmaxidleconns(5) db.setconnmaxlifetime(time.minute * 10) db.setconnmaxidletime(time.minute * 5) err = db.ping() if err != nil { log.fatalf("failed to ping database: %v", err) } fmt.println("successfully connected to database!") rows, err := db.query("select id, name from users") if err != nil { log.fatalf("failed to run query: %v", err) } defer rows.close() for rows.next() { var id int var name string if err := rows.scan(&id, &name); err != nil { log.fatalf("failed to read query results: %v", err) } fmt.printf("id: %d, name: %s ", id, name) } if err := rows.err(); err != nil { log.fatalf("error after iteration: %v", err) } }
我們可以專注于以下代碼段:
db.SetMaxOpenConns(10) db.SetMaxIdleConns(5) db.SetConnMaxLifetime(time.Minute * 10) db.SetConnMaxIdleTime(time.Minute * 5)
這是解釋:
- > setmaxopenconns(10)
:確定可以同時打開的最大連接數。
> setmaxidleconns(5)
:確定池中維護的最大怠速連接數。
> setconnmaxlifetime(time.minute * 10)
:確定連接可以在重置或關閉之前可以持續多長時間。
- > setconnmaxidletime(time.minute * 5)
:確定在關閉之前可以保持多長時間的空閑連接。 結論
- 如果您對上述討論有補充或更正,請在評論列中討論它。希望它有幫助。
連接池的使用非常重要,因為在處理傳入請求的不穩定負載時,可以預見應用程序的運行順利。但是還必須實現正確的設置,以便使用連接池的使用更為最佳。