詳解.NET數(shù)據(jù)庫連接池
一般我們的項目中會使用1到2個數(shù)據(jù)庫連接配置,同程藝龍的數(shù)據(jù)庫連接配置被收攏到統(tǒng)一的配置中心,由DBA統(tǒng)一配置和維護,業(yè)務方通過某個字符串配置拿到的是Connection對象。
DBA能在對業(yè)務方無侵入的情況下,給業(yè)務方切換備份數(shù)據(jù)庫,之后DBA要求舊連接池必須立即被清空, 那么問題來了: dotnet能不能立即清空連接池? 注意我用得是清空,而不是釋放連接。
如果有同學不知道DBA做這個要求的目的,那我啰嗦一下:
應用程序不再使用舊連接時,理論上你的連接池要被完全清空,因為單純的釋放連接,只會讓連接池中的Connection處于Sleep狀態(tài),依舊維持了短時間的物理連接,這個短時間其實是不必要的占用,影響了舊連接數(shù)據(jù)庫的吞吐量。
前置知識背景
回答這個問題之前, 我們還是先研究一下.NET數(shù)據(jù)庫連接池。
1. .NET數(shù)據(jù)庫連接池的背景
數(shù)據(jù)庫連接是一個耗時的行為,大多數(shù)應用程序只使用1到幾種數(shù)據(jù)庫連接,為了最小化打開連接的成本,ado.net使用了一種稱為連接池的優(yōu)化技術(shù)。
2. .NET 數(shù)據(jù)庫連接池的表現(xiàn)
數(shù)據(jù)庫連接池減少了必須打開新連接的次數(shù),池程序維護了數(shù)據(jù)庫物理連接。
通過為每個特定的連接配置保持一組活動的連接對象來管理連接。
每當應用程序嘗試Open連接,池程序就會在池中找到可用的連接,如果有則返回給調(diào)用者;
應用程序Close連接對象時,池程序?qū)⑦B接對象返回到池中(Sleep), 這個連接可以在下一次Open調(diào)用中重用。
看黑板,下面是這次的重點:
3. .NET是如何形成數(shù)據(jù)庫連接池的?
只有相同的連接配置才能被池化,.NET為不同的配置維護了不同的連接池。
相同的配置限制為:
進程相同、
連接字符串相同、
連接字符串關(guān)鍵key順序相同。
(同一連接提供的關(guān)鍵字順序不同將被分到不同的池)。
連接池中的可用連接的數(shù)量由連接字符串Max Pool Size決定。
在一個應用程序中,有如下代碼:
using (SqlConnection connection = new SqlConnection( "Integrated Security=SSPI;Initial Catalog=Northwind")) { connection.Open(); // Pool A is created. } using (SqlConnection connection = new SqlConnection( "Integrated Security=SSPI;Initial Catalog=pubs")) { connection.Open(); // Pool B is created because the connection strings differ. } using (SqlConnection connection = new SqlConnection( "Integrated Security=SSPI;Initial Catalog=Northwind")) { connection.Open(); // The connection string matches pool A. }
上面創(chuàng)建了三個Connection對象,但是只形成了兩個數(shù)據(jù)庫連接池。
還是以上代碼,如果有兩個相同的應用程序,理論上就形成了四個數(shù)據(jù)庫連接池。
4. 連接池中的連接什么時候被移除?
連接池中的連接空閑4-8 分鐘,池程序會移除這個連接。
應用程序下線,連接池直接被清空。
.NET 如何清空連接池?
有了以上知識背景
我們再來回顧一下 DBA的要求,切換原連接配置的時候,清空連接池。
我從官方文檔找到
.NET提供了
ClearAllPools、ClearPool靜態(tài)方法用于清空連接池。
- ClearAllPools: 清空與這個DBProvider相關(guān)的所有連接池
- ClearPool(DBConnection conn) 清空與這個連接對象相關(guān)的連接池
很明顯,我們這次要使用ClearPool(DBConnection conn) 方法。
光說不練不驗證,不是我的風格。
天錘壓測/queryapi 產(chǎn)生一個包含大量連接對象的連接池;
適當?shù)臅r候,/clearpoolapi清空連接池。
public class MySqlController : Controller { // GET: MySql [Route("query")] public string Index() { var s = "User ID=teinfra_neo_netreplay;Password=123456;DataBase=teinfra_neo_netreplay;Server=10.100.41.196;Port=3980;Min Pool Size=1;Max Pool Size=28;CharSet=utf8;"; using (var conn = new MySqlConnection(s)) { var comm = conn.CreateCommand(); comm.CommandText = "select count(*) from usertest;"; conn.Open(); var ret = comm.ExecuteScalar(); comm.CommandText = "select count(*) from information_schema.PROCESSLIST WHERE HOST like '10.22.12.245%';"; var len = comm.ExecuteScalar(); return $"查詢結(jié)果:{ret} ,順便查一下當前連接池的連接對象個數(shù): {len}"; }; } [Route("clearpool")] public string Switch() { var s = "User ID=teinfra_neo_netreplay;Password=123456;DataBase=teinfra_neo_netreplay;Server=10.100.41.196;Port=3980;Min Pool Size=1;Max Pool Size=28;CharSet=utf8;"; using (var conn = new MySqlConnection(s)) { conn.Open(); MySqlConnection.ClearPool(conn); }; using (var conn = new MySqlConnection(s)) { conn.Open(); var comm = conn.CreateCommand(); comm.CommandText = "select count(*) from information_schema.PROCESSLIST WHERE HOST like '10.22.12.245%';"; var len = comm.ExecuteScalar(); return $"之前已經(jīng)清空連接池, 此次查詢連接池有 {v1} 個連接對象"; } } }
1. 經(jīng)過壓測工具
2. mysql數(shù)據(jù)庫對比
mysql的連接數(shù)查詢命令, (host是web服務器IP):
select * from information_schema.PROCESSLIST WHERE HOST like '10.22.12.245%';
3. 調(diào)用/clearpoolapi,清空連接池
bingo,清空連接池的理論得到驗證。
干貨旁白
這是我在同程藝龍最近爬的比較深的坑位,
我從本次實踐中理解了.NET數(shù)據(jù)庫連接池的定義方式、并配套掌握了DBProvider 對于.net連接數(shù)的查詢定位方式。
對祖?zhèn)鞔a的改造,.NET數(shù)據(jù)獲取組件SDK 確實提高了原數(shù)據(jù)庫的吞吐量。
希望本文設計考量、理論+論證的行文思路對于讀者有所幫助, 再次感謝有心讀者取關(guān)、再關(guān)注。
到此這篇關(guān)于詳解.NET數(shù)據(jù)庫連接池的文章就介紹到這了,更多相關(guān).NET數(shù)據(jù)庫連接池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET Core MVC解決控制器同名Action請求不明確的問題
這篇文章主要介紹了ASP.NET Core MVC解決控制器同名Action請求不明確的問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03基于ASP.NET實現(xiàn)日期轉(zhuǎn)為大寫的漢字
在寫代碼時遇到一個需要將日期轉(zhuǎn)換為中文大寫日期的問題,網(wǎng)上找了找,示例不是很多,只有javascript代碼的,下面整理下在ASP.NET中怎么實現(xiàn)。2016-08-08ASP.NET中Validation驗證控件正則表達式特殊符號的說明
本文介紹asp.net中RegularExpressionValidator控件中的幾種特殊字符串使用規(guī)則,并做了代碼演示,希望對大家有所幫助。2016-04-04Asp.net MVC 中利用jquery datatables 實現(xiàn)數(shù)據(jù)分頁顯示功能
這篇文章主要介紹了Asp.net MVC 中利用jquery datatables 實現(xiàn)數(shù)據(jù)分頁顯示功能,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-06-06