詳解.NET數(shù)據(jù)庫(kù)連接池
一般我們的項(xiàng)目中會(huì)使用1到2個(gè)數(shù)據(jù)庫(kù)連接配置,同程藝龍的數(shù)據(jù)庫(kù)連接配置被收攏到統(tǒng)一的配置中心,由DBA統(tǒng)一配置和維護(hù),業(yè)務(wù)方通過(guò)某個(gè)字符串配置拿到的是Connection對(duì)象。

DBA能在對(duì)業(yè)務(wù)方無(wú)侵入的情況下,給業(yè)務(wù)方切換備份數(shù)據(jù)庫(kù),之后DBA要求舊連接池必須立即被清空, 那么問(wèn)題來(lái)了: dotnet能不能立即清空連接池? 注意我用得是清空,而不是釋放連接。
如果有同學(xué)不知道DBA做這個(gè)要求的目的,那我啰嗦一下:
應(yīng)用程序不再使用舊連接時(shí),理論上你的連接池要被完全清空,因?yàn)閱渭兊尼尫胚B接,只會(huì)讓連接池中的Connection處于Sleep狀態(tài),依舊維持了短時(shí)間的物理連接,這個(gè)短時(shí)間其實(shí)是不必要的占用,影響了舊連接數(shù)據(jù)庫(kù)的吞吐量。
前置知識(shí)背景
回答這個(gè)問(wèn)題之前, 我們還是先研究一下.NET數(shù)據(jù)庫(kù)連接池。
1. .NET數(shù)據(jù)庫(kù)連接池的背景
數(shù)據(jù)庫(kù)連接是一個(gè)耗時(shí)的行為,大多數(shù)應(yīng)用程序只使用1到幾種數(shù)據(jù)庫(kù)連接,為了最小化打開(kāi)連接的成本,ado.net使用了一種稱為連接池的優(yōu)化技術(shù)。
2. .NET 數(shù)據(jù)庫(kù)連接池的表現(xiàn)
數(shù)據(jù)庫(kù)連接池減少了必須打開(kāi)新連接的次數(shù),池程序維護(hù)了數(shù)據(jù)庫(kù)物理連接。
通過(guò)為每個(gè)特定的連接配置保持一組活動(dòng)的連接對(duì)象來(lái)管理連接。
每當(dāng)應(yīng)用程序嘗試Open連接,池程序就會(huì)在池中找到可用的連接,如果有則返回給調(diào)用者;
應(yīng)用程序Close連接對(duì)象時(shí),池程序?qū)⑦B接對(duì)象返回到池中(Sleep), 這個(gè)連接可以在下一次Open調(diào)用中重用。
看黑板,下面是這次的重點(diǎn):
3. .NET是如何形成數(shù)據(jù)庫(kù)連接池的?
只有相同的連接配置才能被池化,.NET為不同的配置維護(hù)了不同的連接池。
相同的配置限制為:
進(jìn)程相同、
連接字符串相同、
連接字符串關(guān)鍵key順序相同。
(同一連接提供的關(guān)鍵字順序不同將被分到不同的池)。
連接池中的可用連接的數(shù)量由連接字符串Max Pool Size決定。
在一個(gè)應(yīng)用程序中,有如下代碼:
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)建了三個(gè)Connection對(duì)象,但是只形成了兩個(gè)數(shù)據(jù)庫(kù)連接池。
還是以上代碼,如果有兩個(gè)相同的應(yīng)用程序,理論上就形成了四個(gè)數(shù)據(jù)庫(kù)連接池。
4. 連接池中的連接什么時(shí)候被移除?
連接池中的連接空閑4-8 分鐘,池程序會(huì)移除這個(gè)連接。
應(yīng)用程序下線,連接池直接被清空。
.NET 如何清空連接池?
有了以上知識(shí)背景
我們?cè)賮?lái)回顧一下 DBA的要求,切換原連接配置的時(shí)候,清空連接池。
我從官方文檔找到
.NET提供了
ClearAllPools、ClearPool靜態(tài)方法用于清空連接池。
- ClearAllPools: 清空與這個(gè)DBProvider相關(guān)的所有連接池
- ClearPool(DBConnection conn) 清空與這個(gè)連接對(duì)象相關(guān)的連接池
很明顯,我們這次要使用ClearPool(DBConnection conn) 方法。
光說(shuō)不練不驗(yàn)證,不是我的風(fēng)格。
天錘壓測(cè)/queryapi 產(chǎn)生一個(gè)包含大量連接對(duì)象的連接池;
適當(dāng)?shù)臅r(shí)候,/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} ,順便查一下當(dāng)前連接池的連接對(duì)象個(gè)數(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} 個(gè)連接對(duì)象";
}
}
}
1. 經(jīng)過(guò)壓測(cè)工具

2. mysql數(shù)據(jù)庫(kù)對(duì)比

mysql的連接數(shù)查詢命令, (host是web服務(wù)器IP):
select * from information_schema.PROCESSLIST WHERE HOST like '10.22.12.245%';
3. 調(diào)用/clearpoolapi,清空連接池

bingo,清空連接池的理論得到驗(yàn)證。
干貨旁白
這是我在同程藝龍最近爬的比較深的坑位,
我從本次實(shí)踐中理解了.NET數(shù)據(jù)庫(kù)連接池的定義方式、并配套掌握了DBProvider 對(duì)于.net連接數(shù)的查詢定位方式。
對(duì)祖?zhèn)鞔a的改造,.NET數(shù)據(jù)獲取組件SDK 確實(shí)提高了原數(shù)據(jù)庫(kù)的吞吐量。
希望本文設(shè)計(jì)考量、理論+論證的行文思路對(duì)于讀者有所幫助, 再次感謝有心讀者取關(guān)、再關(guān)注。
到此這篇關(guān)于詳解.NET數(shù)據(jù)庫(kù)連接池的文章就介紹到這了,更多相關(guān).NET數(shù)據(jù)庫(kù)連接池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- .NET 2.0獲取配置文件AppSettings和ConnectionStrings節(jié)數(shù)據(jù)的方法
- 詳解ASP.NET MVC的整個(gè)生命周期
- Asp.net Core 如何設(shè)置黑白名單(路由限制)
- Quartz.NET的具體使用
- C#和vb.net實(shí)現(xiàn)PDF 添加可視化和不可見(jiàn)數(shù)字簽名
- .NET5控制臺(tái)程序使用EF連接MYSQL數(shù)據(jù)庫(kù)的方法
- C#中使用jieba.NET、WordCloudSharp制作詞云圖的步驟
- .NET AppSettings與ConnectionStrings使用案例詳解
相關(guān)文章
TrieTree服務(wù)-組件構(gòu)成及其作用介紹
本文將一步步教你配置和使用TrieTree服務(wù),需要的朋友可以參考下2013-01-01
asp.net 用繼承方法實(shí)現(xiàn)頁(yè)面判斷session
在做ASP項(xiàng)目的時(shí)候,判斷用戶是否登陸常用的方法是在每個(gè)頁(yè)面判斷session是否存在,無(wú)奈用java的時(shí)候過(guò)濾器就用的不熟。。。還是用繼承吧。汗。。。2009-09-09
GridView自定義分頁(yè)實(shí)例詳解(附demo源碼下載)
這篇文章主要介紹了GridView自定義分頁(yè)的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了GridView自定義分頁(yè)所涉及的樣式布局及功能實(shí)現(xiàn)相關(guān)技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2016-03-03
asp.net結(jié)合aspnetpager使用SQL2005的存儲(chǔ)過(guò)程分頁(yè)
項(xiàng)目中用到了,同事阿春寫(xiě)了例子,并在實(shí)際項(xiàng)目中使用了,記錄下。感謝春哥的無(wú)私奉獻(xiàn)。2009-07-07
ASP.NET使用My97DatePicker日期控件實(shí)例
這篇文章主要為大家詳細(xì)介紹了ASP.NET使用My97DatePicker日期控件實(shí)例,如何使用My97DatePicker日期控件,本文為大家介紹,感興趣的小伙伴們可以參考一下2016-04-04
asp.net中頁(yè)面顯示當(dāng)前系統(tǒng)時(shí)間附圖
asp.net如何實(shí)現(xiàn)在頁(yè)面顯示當(dāng)前系統(tǒng)時(shí)間,本文有個(gè)不錯(cuò)的方法,大家可以嘗試操作下,在文章末尾有截圖2013-12-12
asp.net基礎(chǔ)學(xué)習(xí)之控件的使用方法
這篇文章主要為大家詳細(xì)介紹了asp.net基礎(chǔ)學(xué)習(xí)之控件的使用方法,感興趣的小伙伴們可以參考一下2016-08-08
C#中使用SQLite數(shù)據(jù)庫(kù)的方法介紹
SQLite是一個(gè)開(kāi)源的輕量級(jí)的桌面型數(shù)據(jù)庫(kù),它將幾乎所有數(shù)據(jù)庫(kù)要素(包括定義、表、索引和數(shù)據(jù)本身)都保存在一個(gè)單一的文件中。SQLite用C編寫(xiě)實(shí)現(xiàn),它在內(nèi)存消耗、文件體積、操作性能、簡(jiǎn)單性方面都有不錯(cuò)的表現(xiàn)2012-01-01

