SqlServer資料庫連線數與客戶端連線池關係測試(一)
連線池連線數 |
DB連線數 |
峰值錯誤資訊 |
連線峰值 |
40000 |
0(32767) |
? |
? |
3000 |
0(32767) |
? |
? |
40000 |
3000 |
? |
? |
主要測試上面的結果,不多說了,直接操作吧!
測試程式碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Data.SqlClient; namespace dbConnectionTest { class Program { static void Main(string[] args) { int maxCount = 40000; string connstring = "Server=1card1-hzc;Database=mytest;User ID=sa;Password=sa;pooling=true;connection lifetime=0;min pool size = 1;max pool size=40000"; List<SqlConnection> collection = new List<SqlConnection>(); for (int i = 0; i < maxCount; i++) { Console.WriteLine(string.Format("已建立連線物件{0}", i)); try { var sqlConn = new SqlConnection(connstring); sqlConn.Open(); collection.Add(sqlConn);//儲存連線物件 } catch (Exception e) { Console.WriteLine(e.Message); } } } } }
檢視資料庫設定的最大連線數,[userconnections] run_value=0(為0預設最大值32767)
測試一:
設定max poolsize=40000,即連線池40000,資料庫32767。執行指令碼!
監控可以看到,峰值為32717,加上資料庫系統自己的50個連線,總數為32767,即為資料庫的最大連線數。
(在連線過程中,CPU和記憶體開銷很大!)
在出錯的情況下還繼續建立物件,但是資料庫連線數是沒有增加的,連線物件都儲存到連線池中,等待連線資料庫。
當連線池連線數達到最大值時,如下圖到達39999時,程式自動關閉退出!本人電腦幾乎卡死!資料庫連線數回到正常,資料庫記憶體仍然很到,還是很卡!
測試二:
設定max poolsize=3000,即連線池3000,資料庫32767。執行指令碼!
連線池最大連線為3000,再新建連線時,因超時不能新增到連線池中,失敗!
資料庫當前最多可連線32767,現在只連線3000+系統session,為3019,還可以繼續連線,只是連線池限制。
正常業務情況下,連線池會盡快處理沒有用的連線,讓客戶端建立新的連線。
在資料庫中,我刪除1000個sleeping的session:
declare @i int set @i = 1000 while @i<2000 begin exec('kill '+ @i) SET @i = @i + 1 end
資料庫連線是降下來了,但是連線池還是沒有降。因為心的連線還是無法通過連線池。所有也不要刪除資料庫中sleeping的session,因為連線池如果再重用連線的話,找不到資料庫中的對應連線就斷開了!
測試三:
這次設定max poolsize=40000,即連線池40000,資料庫3000。
資料庫中執行以下程式碼,然後重啟資料庫服務:
EXEC sp_configure 'user connections',3000
Reconfigure
執行指令碼!
當通過連線池連線資料達到2982時,發生錯誤。加上資料庫系統中的18個session,連線總數為3000.
這個錯誤網上很常見,連線池雖然可以繼續建立新的連線,但是無法與資料庫端連線。出現此錯誤可以判斷是資料庫端沒法連線到。如果不是最大連線數出錯,可能是tcp/ip協議未開啟、埠未開啟或被隔離等。。
成功與伺服器建立連線,但是在登入前的握手期間發生錯誤。(provider:tcp provider error:0 –指定的網路名不可再用。)
接下來在資料庫中,刪除1000個sleeping的session:
declare @i int
set @i = 1000
while @i<2000
begin
exec('kill '+ @i)
SET @i = @i + 1
end
連線又可以正常進行了。
結果:
連線池連線數 |
DB連線數 |
峰值錯誤資訊 |
連線峰值 |
40000 |
0(32767) |
當前命令發生了嚴重錯誤,應放棄任何可能產生的結果。 |
32717 |
3000 |
0(32767) |
超時時間已到,但是尚未從池中獲取連線,出現這種情況可能是因為所有池連線均在使用,並達到最大池大小。 |
3000+系統 |
40000 |
3000 |
成功與伺服器建立連線,但是在登入前的握手期間發生錯誤。 (provider:tcp provider error:0 – 指定的網路名不可再用。) |
3000 |
參考: