Sql Server 连接池
在看緩存的一篇文章中,看到連接池的三個(gè)字,來充充電。
原文連接?這篇講了關(guān)鍵字
其實(shí)我們一直在使用SqlServer的連接池。在連接字符串中,Pooling為是否啟用連接池,默認(rèn)值為true,表示啟用;可以在鏈接后面加上Pooling=true;的屬性。
與連接池相關(guān)的兩個(gè)重要參數(shù)是 Min Pool Size和 Max Pool Size ,分別是池中的最小連接數(shù)和池中的最大連接數(shù),默認(rèn)值分別是0和100.
在我們創(chuàng)建一個(gè)連接的實(shí)例,并調(diào)用Open()方法時(shí),連接池管理程序會(huì)在連接池中找到一個(gè)可用的連接;當(dāng)調(diào)用Close()方法時(shí),連接池管理程序又將連接返回到連接池中,以供下一次調(diào)用Open()方法時(shí)使用.
連接字符串中的 Connection Lifetime 為連接池中的連接設(shè)置了生命周期。它的默認(rèn)值為0。
當(dāng)連接被返回到池時(shí),將其創(chuàng)建時(shí)間與當(dāng)前時(shí)間作比較,如果時(shí)間長(zhǎng)度(以秒為單位)超出了由?Connection Lifetime?指定的值,該連接就會(huì)被銷毀。
這在聚集配置中很有用(用于強(qiáng)制執(zhí)行運(yùn)行中的服務(wù)器和剛置于聯(lián)機(jī)狀態(tài)的服務(wù)器之間的負(fù)載平衡)。零(0)值將使連接池具有最大的連接超時(shí)。?
通過上面的了解,我們可以看出,即使是最簡(jiǎn)單的連接字符串,也在使用連接池。
感覺:“鏈接”就像是一個(gè)人,歸于“連接池管理程序”管理,當(dāng)"外界"需要鏈接實(shí)例的時(shí)候,回到管理程序中去找一個(gè)可以用的;如果這個(gè)“鏈接”工作完回來后超過規(guī)定時(shí)間還有可能被殺死。。。。
asp.net 連接池
數(shù)據(jù)庫鏈接是一種危險(xiǎn)的、昂貴的、有限的資源,特別是在多層Web應(yīng)用程序中。你必須正確管理你的鏈接,因?yàn)槟愕姆椒▽O大的影響應(yīng)用程序的整體升級(jí)性。
高性能應(yīng)用程序與使用中的數(shù)據(jù)源保持最短時(shí)間的連接,并且利用性能增強(qiáng)技術(shù),例如連接池。
連接池用于ODBC 的 SQL Server、OLE DB 和 .NET 框架數(shù)據(jù)提供程序隱式緩沖連接。通過在連接字符串中指定不同的屬性值,可以控制連接池的行為。
連接池概述
數(shù)據(jù)庫鏈接池使應(yīng)用程序能夠重用池中的現(xiàn)有鏈接,而不是重復(fù)地建立對(duì)數(shù)據(jù)庫的鏈接。這種技術(shù)將極大地增加應(yīng)用程序的可擴(kuò)展性,因?yàn)橛邢薜臄?shù)據(jù)庫鏈接可以為很多的客戶提供服務(wù)。此技術(shù)也將提高性能,因?yàn)?span style="color:#ff0000;">能夠避免用于建立新鏈接的巨大時(shí)間。
具體來說,大多數(shù) ADO.NET 數(shù)據(jù)提供程序使用連接池,以提高圍繞 Microsoft 斷開連接的 .NET 結(jié)構(gòu)構(gòu)建的應(yīng)用程序的性能。應(yīng)用程序首先打開一個(gè)連接(或從連接池獲得一個(gè)連接句柄),接著運(yùn)行一個(gè)或多個(gè)查詢,然后處理行集,最后將連接釋放回連接池。如果沒有連接池,這些應(yīng)用程序?qū)⒒ㄙM(fèi)許多額外時(shí)間來打開和關(guān)閉連接。
下面將以SQL Server .NET Framework 數(shù)據(jù)提供程序連接池為例來說明連接池的一些性能和用法。(另外還有ODBC .NET Framework 數(shù)據(jù)提供程序連接池、OLE DB .NET Framework 數(shù)據(jù)提供程序連接池。)
池的創(chuàng)建和分配
當(dāng)連接打開時(shí),將根據(jù)一種精確的匹配算法來創(chuàng)建連接池,該算法會(huì)使連接池與連接中的字符串相關(guān)聯(lián)。每個(gè)連接池都與一個(gè)不同的連接字符串相關(guān)聯(lián)。
當(dāng)新連接打開時(shí),如果連接字符串不精確匹配現(xiàn)有池,則將創(chuàng)建一個(gè)新池。
在以下示例中,將創(chuàng)建三個(gè)新的 SqlConnection 對(duì)象,但只需要使用兩個(gè)連接池來管理這些對(duì)象。請(qǐng)注意,第一個(gè)和第二個(gè)連接字符串的差異在于為 Initial Catalog 分配的值
SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind"; conn.Open(); // Pool A is created. SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=pubs"; conn.Open(); // Pool B is created because the connection strings differ. SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Integrated Security=SSPI;Initial Catalog=northwind"; conn.Open(); // The connection string matches pool A.連接池一旦創(chuàng)建,直到活動(dòng)進(jìn)程終止時(shí)才會(huì)被毀壞。非活動(dòng)或空池的維護(hù)只需要最少的系統(tǒng)開銷。
在使用SQL Server .NET數(shù)據(jù)供應(yīng)器鏈接池時(shí),必須清楚:
鏈接是通過對(duì)鏈接字符串精確匹配的法則被池化的。
池化機(jī)制對(duì)名稱-值對(duì)間的空格敏感。例如,下面的兩個(gè)鏈接字符串將生成單獨(dú)的池,因?yàn)榈诙€(gè)字符串包含了一個(gè)額外的空字符。
SqlConnection conn = new SqlConnection("Integrated Security=SSPI;Database=Northwind");
conn.Open(); // Pool A is created
SqlConmection conn = new SqlConnection("Integrated Security=SSPI ; Database=Northwind");
conn.Open(); // Pool B is created (extra spaces in string)
總結(jié):1:在鏈接創(chuàng)建時(shí),就會(huì)建立一個(gè)連接池,相同的鏈接會(huì)創(chuàng)建一個(gè)連接池;只要鏈接不一樣就會(huì)創(chuàng)建出來另外的一個(gè)連接池(黃字)
? ? ? ? ? ?2:創(chuàng)建連接池是要消耗資源的,就是這個(gè)鏈接不用也占用CPU;
? ? ? ? ? ?3:當(dāng)這個(gè)鏈接在用的時(shí)候,其他的請(qǐng)求要等到這個(gè)釋放了,才能用,要在連接池中等待;
? ? ? ? ? ?4:連接池貌似有個(gè)屬性,可以限制最多多少個(gè)鏈接
連接的添加
連接池是為每個(gè)唯一的連接字符串創(chuàng)建的。當(dāng)創(chuàng)建一個(gè)池后,將創(chuàng)建多個(gè)連接對(duì)象并將其添加到該池中,以滿足最小池大小的要求。連接將根據(jù)需要添加到池中,直至達(dá)到最大池大小。
當(dāng)請(qǐng)求 SqlConnection 對(duì)象時(shí),如果存在可用的連接,則將從池中獲取該對(duì)象。若要成為可用連接,該連接當(dāng)前必須未被使用,具有匹配的事務(wù)上下文或者不與任何事務(wù)上下文相關(guān)聯(lián),并且具有與服務(wù)器的有效鏈接。
如果已達(dá)到最大池大小且不存在可用的連接,則該請(qǐng)求將會(huì)排隊(duì)。當(dāng)連接被釋放回池中時(shí),連接池管理程序通過重新分配連接來滿足這些請(qǐng)求。對(duì) Connection 調(diào)用 Close 或 Dispose 時(shí),連接被釋放回池中。
連接的移除
如果連接生存期已過期,或者連接池管理程序檢測(cè)到與服務(wù)器的連接已斷開,連接池管理程序?qū)某刂幸瞥撨B接。請(qǐng)注意,只有在嘗試與服務(wù)器進(jìn)行通信后,才可以檢測(cè)到這種情況。如果發(fā)現(xiàn)某連接不再連接到服務(wù)器,則會(huì)將其標(biāo)記為無效。連接池管理程序會(huì)定期掃描連接池,查找已釋放到池中并標(biāo)記為無效的對(duì)象。找到后,這些連接將被永久移除。
如果存在與已消失的服務(wù)器的連接,那么即使連接池管理程序未檢測(cè)到已斷開的連接并將其標(biāo)記為無效,仍有可能將此連接從池中取出。當(dāng)發(fā)生這種情況時(shí),將生成異常。但是,為了將該連接釋放回池中,仍必須將其關(guān)閉。
選擇池容量
能建立最大極限對(duì)于管理幾千用戶同時(shí)發(fā)出請(qǐng)求的大型系統(tǒng)來說是非常重要的。你需要監(jiān)視鏈接池及應(yīng)用程序的性能,以確定系統(tǒng)的最優(yōu)池容量。最優(yōu)容量還要依賴于運(yùn)行SQL Server的硬件。
在開發(fā)期間,也許需要減小默認(rèn)的最大池容量(目前是100)以幫助查找鏈接泄漏。
如果設(shè)立了最小池容量,那么當(dāng)池最初被填充以達(dá)到該值時(shí),會(huì)導(dǎo)致一些性能損失,盡管最初鏈接的幾個(gè)客戶會(huì)從中受益。注意,創(chuàng)建新鏈接的過程被序列化了,這就意味著當(dāng)池最初被填充時(shí),服務(wù)器無法處理同時(shí)發(fā)生的請(qǐng)求。
監(jiān)視鏈接池化
要監(jiān)視應(yīng)用程序?qū)︽溄映鼗膽?yīng)用情況,可以使用隨SQL Server發(fā)行的Profiler工具,或隨微軟Windows 2000發(fā)行的性能監(jiān)視器。
要利用SQL Server Profiler 監(jiān)視鏈接池化,操作如下:
1. ? ? ? ? 單擊開始,指向程序,指向Microsoft SQL Server,然后單擊Profiler運(yùn)行Profiler。
2. ? ? ? ? 在文件菜單中,指向新建,然后單擊跟蹤。
3. ? ? ? ? 提供鏈接內(nèi)容,然后單擊確定。
4. ? ? ? ? 在跟蹤屬性對(duì)話框中,單擊事件標(biāo)簽。
5. ? ? ? ? 在已選事件類別列表中,確保審核登錄和審核登出事件顯示在安全審核下面。
6. ? ? ? ? 單擊運(yùn)行開始跟蹤。在鏈接建立時(shí),將會(huì)看到審核登錄事件;在鏈接關(guān)閉時(shí)看到審核登出事件。
要通過性能監(jiān)視器監(jiān)視鏈接池化,操作如下:
1. ? ? ? ? 單擊開始,指向程序,指向管理工具,然后單擊性能運(yùn)行性能監(jiān)視器。
2. ? ? ? ? 在圖表背景中右擊,然后單擊增加計(jì)數(shù)器。
3. ? ? ? ? 在性能對(duì)象下拉列表框中,單擊SQL Server:通用統(tǒng)計(jì)。
4. ? ? ? ? 在出現(xiàn)的列表中,單擊用戶鏈接。
5. ? ? ? ? 單擊增加,然后單擊關(guān)閉。
在config中加pooling=false,說明程序中不用連接池。
在config文件的連接字符串中增加max pool size ="1000" 擴(kuò)大連接池,同時(shí),調(diào)整程序,盡量避免多開連接。
?
?Connection Pool 是什么呢 ?(是將已經(jīng)創(chuàng)建好的數(shù)據(jù)庫的鏈接,先不關(guān)閉,放到連接池中;這樣下次再用的時(shí)候可以直接從池中拿取,不需要再創(chuàng)建新的了)
每當(dāng)程序需要讀寫數(shù)據(jù)庫的時(shí)候。Connection.Open()會(huì)使用ConnectionString連接到數(shù)據(jù)庫,數(shù)據(jù)庫會(huì)為程序建立 一個(gè)連接,并且保持打開狀態(tài),此后程序就可以使用T-SQL語句來查詢/更新數(shù)據(jù)庫。當(dāng)執(zhí)行到Connection.Close()后,數(shù)據(jù)庫就會(huì)關(guān)閉當(dāng) 前的連接。很好,一切看上去都是如此有條不紊。?
但是如果我的程序需要不定時(shí)的打開和關(guān)閉連接,(比如說 ASP.Net 或是 Web Service ),例如當(dāng)Http Request發(fā)送到服務(wù)器的時(shí)候、,我們需要打開Connection 然后使用Select* from Table 返回一個(gè)DataTable/DataSet給客戶端/瀏覽器,然后關(guān)閉當(dāng)前的Connection。那每次都Open/Close Connection 如此的頻繁操作對(duì)于整個(gè)系統(tǒng)無疑就成了一種浪費(fèi)。?
ADO.Net Team就給出了一個(gè)比較好地解決方法。將先前的Connection保存起來,當(dāng)下一次需要打開連接的時(shí)候就將先前的Connection 交給下一個(gè)連接。這就是Connection Pool。
首先當(dāng)一個(gè)程序執(zhí)行Connection.open()時(shí)候,ADO.net就需要判斷,此連接是否支持Connection Pool (Pooling 默認(rèn)為True),如果指定為False, ADO.net就與數(shù)據(jù)庫之間創(chuàng)建一個(gè)連接(為了避免混淆,所有數(shù)據(jù)庫中的連接,都使用”連接”描述),然后返回給程序。
如果指定為 True,ADO.net就會(huì)根據(jù)ConnectString創(chuàng)建一個(gè)Connection Pool,然后向Connection Pool中填充Connection(所有.net程序中的連接,都使用”Connection”描述)。填充多少個(gè)Connection由Min Pool Size (默認(rèn)為0)屬性來決定。 例如如果指定為5,則ADO.net會(huì)一次與SQL數(shù)據(jù)庫之間打開5個(gè)連接,然后將4個(gè)Connection,保存在 Connection Pool中,1個(gè)Connection返回給程序。
?
當(dāng)程序執(zhí)行到Connection.close() 的時(shí)候。如果Pooling 為True,ADO.net 就把當(dāng)前的Connection放到Connection Pool并且保持與數(shù)據(jù)庫之間的連接。
同時(shí)還會(huì)判斷Connection Lifetime(默認(rèn)為0)屬性,0代表無限大,如果Connection存在的時(shí)間超過了Connection LifeTime,ADO.net就會(huì)關(guān)閉的Connection同時(shí)斷開與數(shù)據(jù)庫的連接,而不是重新保存到Connection Pool中。
(這個(gè)設(shè)置主要用于群集的SQL 數(shù)據(jù)庫中,達(dá)到負(fù)載平衡的目的)。如果Pooling指定為False,則直接斷開與數(shù)據(jù)庫之間的連接。
?
然后當(dāng)下一次Connection.Open() 執(zhí)行的時(shí)候,ADO.Net就會(huì)判斷新的ConnectionString與之前保存在Connection Pool中的Connection的connectionString是否一致。
(ADO.Net會(huì)將ConnectionString轉(zhuǎn)成二進(jìn)制流,所 以也就是說,新的ConnectionString與保存在Connection Pool中的Connection的ConnectionString必須完全一致,即使多加了一個(gè)空格,或是修改了Connection String中某些屬性的次序都會(huì)讓ADO.Net認(rèn)為這是一個(gè)新的連接,而從新創(chuàng)建一個(gè)新的連接。所以如果您使用的UserID,Password的認(rèn) 證方式,修改了Password也會(huì)導(dǎo)致一個(gè)Connection,如果使用的是SQL的集成認(rèn)證,就需要保存兩個(gè)連接使用的是同一個(gè))。
然后 ADO.net需要判斷當(dāng)前的Connection Pool中是否有可以使用的Connection(沒有被其他程序所占用),如果沒有的話,ADO.net就需要判斷ConnectionString設(shè) 置的Max Pool Size (默認(rèn)為100),如果Connection Pool中的所有Connection沒有達(dá)到Max Pool Size,ADO.net則會(huì)再次連接數(shù)據(jù)庫,創(chuàng)建一個(gè)連接,然后將Connection返回給程序。
如果已經(jīng)達(dá)到了 MaxPoolSize,ADO.net就不會(huì)再次創(chuàng)建任何新的連接,而是等待Connection Pool中被其他程序所占用的Connection釋放,這個(gè)等待時(shí)間受SqlConnection.ConnectionTimeout(默認(rèn)是15 秒)限制,也就是說如果時(shí)間超過了15秒,SqlConnection就會(huì)拋出超時(shí)錯(cuò)誤(所以有時(shí)候如果SqlConnection.open()方法拋 出超時(shí)錯(cuò)誤,一個(gè)可能的原因就是沒有及時(shí)將之前的Connnection關(guān)閉,同時(shí)Connection Pool數(shù)量達(dá)到了MaxPoolSize。)
如果有可用的Connection,從Connection Pool 取出的Connection也不是直接就返回給程序,ADO.net還需要檢查ConnectionString的ConnectionReset屬性 (默認(rèn)為True)是否需要對(duì)Connection 最一次reset。這是由于,之前從程序中返回的Connection可能已經(jīng)被修改過,比如說使用 SqlConnection.ChangeDatabase method 修改當(dāng)前的連接,此時(shí)返回的Connection可能就已經(jīng)不是連接當(dāng)前的Connection String指定的Initial Catalog數(shù)據(jù)庫了。所以需要reset一次當(dāng)前的連接。但是由于所有的額外檢查都會(huì)增大ADO.net Connection Pool 對(duì)系統(tǒng)的開銷。
?
?
?
?
?
?
查看連接數(shù)相關(guān)
1、獲取SQL Server允許同時(shí)用戶連接的最大數(shù)
SELECT @@MAX_CONNECTIONS
2、獲取當(dāng)前指定數(shù)據(jù)庫的連接信息
?
3、獲取當(dāng)前SQL服務(wù)器所有的連接詳細(xì)信息
SELECT * FROM sysprocesses
以上查詢結(jié)果包含了:系統(tǒng)進(jìn)程和用戶進(jìn)程。
如果只是想查用戶進(jìn)程的話則需采用下面的方法
4、獲取自上次啟動(dòng) SQL Server服務(wù) 以來連接或試圖連接的次數(shù)
SELECT @@CONNECTIONS
5 ---查看當(dāng)前數(shù)據(jù)庫系統(tǒng)所有請(qǐng)求情況.
只列出了我認(rèn)為比較重要有助于我解決問題的字段。
1 SELECT ds.session_id, 2 ds.status, 3 Db_name(dr.database_id) AS database_name, 4 ds.login_name, 5 ds.login_time, 6 ds.host_name, 7 dc.client_net_address, 8 dc.client_tcp_port, 9 ds.program_name, 10 dr.cpu_time, 11 dr.reads, 12 dr.writes, 13 dc.num_reads, 14 dc.num_writes, 15 ds.client_interface_name, 16 ds.last_request_start_time, 17 ds.last_request_end_time, 18 dc.connect_time, 19 dc.net_transport, 20 dc.net_packet_size, 21 dr.start_time, 22 dr.status, 23 dr.command, 24 dr.blocking_session_id, 25 dr.wait_type, 26 dr.wait_time, 27 dr.last_wait_type, 28 dr.wait_resource, 29 dr.open_transaction_count, 30 dr.percent_complete, 31 dr.granted_query_memory 32 FROM Sys.dm_exec_requests dr WITH(nolock) 33 RIGHT OUTER JOIN Sys.dm_exec_sessions ds WITH(nolock) 34 ON dr.session_id = ds.session_id 35 RIGHT OUTER JOIN Sys.dm_exec_connections dc WITH(nolock) 36 ON ds.session_id = dc.session_id 37 WHERE ds.session_id > 50 38 ORDER BY ds.program_name View Code用戶連接數(shù)
?
?
?
?主函數(shù):
方法:
?
轉(zhuǎn)載于:https://www.cnblogs.com/ZkbFighting/p/9564648.html
總結(jié)
以上是生活随笔為你收集整理的Sql Server 连接池的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Luogu 3008 [USACO11J
- 下一篇: 洛谷2051 [AHOI2009]中国象