日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

云计算之路-阿里云上:数据库连接数过万的真相,从阿里云RDS到微软.NET Core

發布時間:2025/3/14 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 云计算之路-阿里云上:数据库连接数过万的真相,从阿里云RDS到微软.NET Core 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在昨天的博文中,我們堅持認為數據庫連接數過萬是阿里云RDS的問題,但后來阿里云提供了當時的數據庫連接情況,讓我們動搖了自己的想法。

帳戶連接數
A4077
B3995
C741
D698
E519

上面這5個帳戶產生了10030個數據庫連接,當看前4個帳戶(產生了9511個連接)的名稱時,我們打了一個寒顫 —— 這些都是運行 Linux 上的 ASP.NET Core 站點。。。這不是巧合,其中必有蹊蹺。

隨后,我們觀察了主備庫切換后的 RDS 中數據庫連接情況。有一個運行在 Linux 上的 ASP.NET Core 站點,用了3臺服務器,卻產生了1528個數據庫連接。

SELECT * FROM sys.sysprocesses WHERE loginame='xxx'

重啟其中1臺服務器上的站點,連接數立馬從1528降到了391。什么情況?數據庫連接池發飆了?

繼續觀察,當前數據庫中大量的連接都是由運行在 Linux 上的 ASP.NET Core 站點產生的,而且會隨著時間的推移保持增長。

數據庫連接泄漏了,這還是第1次遇到!可我們在 APS.NET Core 應用中所有的數據庫操作都用的是Entity Framework Core,不存在沒有及時關閉數據庫連接的情況,唯一可以懷疑的對象是在 System.Data.SqlClient 中實現的 ADO.NET 數據庫連接池。

數據庫連接池究竟出什么狀況了?我們在數據庫連接字符串中沒有另外設置連接池,用的是默認設置(Min_Pool_Size = 0; 與 Max_Pool_Size = 100;)。而且更奇怪的是 Max_Pool_Size 的限制沒起作用,不然只會報下面的錯誤,不會連接數一直增長。

Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

我們想來想去,唯一能想得通的解釋是 .NET Core 的數據庫連接池發生了這樣的狀況 —— 連接池中已經創建的連接無法被重用,不僅如此,而且它們直接被 SqlClient 給無視了,都沒有被計算在 Pool Size 中,所以根本觸發不了 Max_Pool_Size 的限制,造成連接無限制,任由 SqlClient 建。更要命的是,這些被無視的連接卻一直在保持著與數據庫的連接。于是,連接泄露成了命中注定。

在有了這個唯一想得通的猜測后,我們今天開始在測試環境中進行驗證。

部署一個 ASP.NET Core 站點,創建一個專用數據庫連接帳戶,然后用下面的 SQL 語句查看數據庫連接是否被重用,同時在測試服務器用 tcpdump 進行抓包,并且分別用阿里云 RDS 與我們自己搭建的 SQL Server 服務器進行測試。

SELECT * from sys.sysprocesses where loginame='測試專用帳戶'

如果連接池正常工作,第1次訪問,新建所需的數據庫連接;第2次訪問同樣的頁面,應該重用已有的數據庫連接,不會創建新的數據庫連接。

開始測試時,不管連接阿里云 RDS 還是我們自己的 SQL Server,連接池都工作正常,連接能被重用。

后來分析了一下,雖然生產環境中連接數一直在增長,但增長速度不是很快,可能問題的發生需要一定的時間間隔,或許連接閑置超過一定時間之后才不會被重用。

于是,我們間隔了10分鐘左右進行訪問測試,問題重現了!比如其中的一次測試,同一個頁面第1次訪問,產生了5個連接;過10分鐘左右再訪問,會新建3個連接變成8個連接;再過10分鐘左右訪問,連接增長到11個。這種連接不能被重用的情況通過 tcp 抓包也可以看出來。如果在很短的時間內訪問,連接數保持不變(連接被重用)。

這個問題不僅在阿里云 RDS (SQL Server 2008 R2)可以重現,而且在我們自己搭建的 SQL Server 2014 也能重現,問題的真相隨之水落石出。

數據庫連接數過萬問題不是阿里云 RDS 的問題,而是 .NET Core 中 System.Data.SqlClient 的連接池在 Linux 上的實現問題,我們錯怪了阿里云,輕信了微軟。這是我們使用阿里云以來對阿里云最大的一次誤會,這是我們 .NET Core 遷移過程中遇到的最大的一個坑。

為什么最近才出現這個問題?是因為我們最近將更多站點遷移到了 ASP.NET Core ,而且將之前一些跑在 Windows 上的 ASP.NET Core 站點切換到了 Linux 。

如何解決這個問題?我們會察看一下 System.Data.SqlClient 的實現代碼,看能否找到實現層面的線索。阿里云會進一步驗證這個問題,如果確認是微軟實現上的問題,會與微軟溝通解決。

【16:55 更新】

我們在 Windows 上進行對比測試發現,在 Windows 上連接池中閑置的數據庫連接過段時間會被自動關閉,與上面 Linux 同樣的測試場景,間隔10分鐘后查看,數據庫連接全消失了。

【18:18 更新】

感謝 @feiyun0112 在評論中提供的線索,2016年11月7日就有人發現了這個問題,并且在 github 上提交了 issue 。

【18:41 更新】

我們在應用中使用的 System.Data.SqlClient.dll 版本是 4.3.0,是在2016年11月5日生成的,正好在這個 issue 之前。

【20:56 更新-成功解決】

通過手動替換 System.Data.SqlClient.dll 文件解決了這個問題。操作步驟如下:

1)在 https://github.com/dotnet/corefx/releases 下載 .NET Core 1.1 得到 corefx-1.1.0.zip 文件并解壓。

2)在 corefx-1.1.0 文件中運行 init-tools.cmd 命令安裝 build 工具

3)用 VS2017 打開 corefx-1.1.0\src\System.Data.SqlClient 中的 System.Data.SqlClient.sln 解決方案

4)打開 SNITcpHandle.cs ,去掉?private readonly NetworkStream _tcpStream; 中的?readonly ,在?Dispose() 方法中添加如下代碼:

if (_tcpStream != null) {_tcpStream.Dispose();_tcpStream = null; }

5)用 VS2017 以 Release 方式 build System.Data.SqlClient 項目。

6)將 corefx-1.1.0\bin\Unix.AnyCPU.Release\System.Data.SqlClient 文件夾中生成的?System.Data.SqlClient.dll 文件,在 git bash 中通過 scp 命令上傳到 Linux 服務器上的 nuget 文件夾。

MINGW64 /c/Dev/GitHub/corefx-1.1.0/bin/Unix.AnyCPU.Release/System.Data.SqlClient $ scp System.Data.SqlClient.dll root@ubuntu-server:~/.nuget/packages/system.data.sqlclient/4.3.0/runtimes/unix/lib/netstandard1.3 System.Data.SqlClient.dll 100% 708KB 176.9KB/s 00:04

7)登錄 Linux 服務器重啟 ASP.NET Core 站點

8)第一次訪問,在數據庫中看到了這些新建的連接,然后停止訪問。。。等了5-6分鐘,這些連接全部消失,和在 Windows 上的表現一致,連接泄露的問題搞定!

連接泄露引起的數據庫連接數過萬的問題,僅僅是因為少寫了1行 Dispose 代碼。

附:我們 build 出來的修復這個問題的 System.Data.SqlClient.dll

【23:15 更新】

更新 System.Data.SqlClient.dll 之后,效果是立竿見影!

轉載于:https://www.cnblogs.com/cmt/p/6677613.html

總結

以上是生活随笔為你收集整理的云计算之路-阿里云上:数据库连接数过万的真相,从阿里云RDS到微软.NET Core的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。