云计算之路-阿里云上:数据库连接数过万的真相,从阿里云RDS到微软.NET Core
在昨天的博文中,我们坚持认为数据库连接数过万是阿里云RDS的问题,但后来阿里云提供了当时的数据库连接情况,让我们动摇了自己的想法。
| 帐户 | 连接数 |
| A | 4077 |
| B | 3995 |
| C | 741 |
| D | 698 |
| E | 519 |
上面这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 之后,效果是立竿见影!

云计算之路-阿里云上:数据库连接数过万的真相,从阿里云RDS到微软.NET Core的更多相关文章
- 云计算之路-阿里云上:RDS数据库连接数过万引发故障,主备库切换后恢复正常
非常抱歉!今天 12:03-12:52 ,由于数据库连接数异常突增超过1万,达到了阿里云RDS的最大连接数限制,影响了全站的正常访问.由此给您带来麻烦,请您谅解. 在发现数据库连接数突增的问题后,我们 ...
- 云上的芯脏病:奇怪的阿里云 RDS 数据库突发 CPU 近 100% 问题
最近遇到了奇怪的阿里云 RDS 数据库突发 CPU 近 100% 问题,遇到了3次. 第一次是10月12日(周六)凌晨 3:24 负载极低的时候开始出现,早上发现后进行了主备切换,恢复了正常. 第二次 ...
- 云计算之路-试用Azure:数据库备份压缩文件在虚拟机上的恢复速度测试
测试环境:Windows Azure上海机房,虚拟机配置为大型(四核,7 GB 内存),磁盘情况见下图. 数据库备份压缩文件大于为12.0 GB (12,914,327,552 bytes),放置于T ...
- 在腾讯云上把Laravel整合万向优图图片管理能力,打造高效图片处理服务
推荐理由: 现如今数据爆炸性增长,人类生活产出的数据越来越多,文字信息,图片信息,视频信息:但有很多信息我们都无法直接使用,需通过一定的处理,才能够获取其中对我们有用的信息,在腾讯云上的万向优图能够对 ...
- 即插即用,基于阿里云Ganos快速构建云上开源GIS方案
对于轻量级GIS应用,选择具备时空能力的云上数据库再搭配开源GIS软件,能够快速构建稳定.廉价.实用的GIS解决方案.Ganos是阿里云自研时空基础设施(PaaS层)的核心引擎,该引擎整合了云上异构计 ...
- 云栖干货回顾 | 云原生数据库POLARDB专场“硬核”解析
POLARDB是阿里巴巴自主研发的云原生关系型数据库,目前兼容三种数据库引擎:MySQL.PostgreSQL.Oracle.POLARDB的计算能力最高可扩展至1000核以上,存储容量可达100TB ...
- 云计算之路-阿里云上:OCS问题的进展以及11:30-11:50遇到的问题
(上图是今天出问题期间Web服务器性能监控图,紫色表示的是Request Execution Time) 昨天我们发布了一篇博客分享了我们这两天遇到的OCS(开放缓存服务)问题,详见云计算之路-阿里云 ...
- 云计算之路-阿里云上:Web服务器遭遇奇怪的“黑色30秒”问题
今天下午访问高峰的时候,主站的Web服务器出现奇怪的问题,开始是2台8核8G的云服务器(ECS),后来又加了1台8核8G的云服务器,问题依旧. 而且3台服务器特地使用了不同的配置:1台是禁用了虚拟内存 ...
- 云计算之路-阿里云上:愚人节被阿里云OCS愚
今天是愚人节,而我们却被阿里云OCS愚,很多地方的缓存一直不过期,造成很多页面中的数据一直不更新.这篇博文将向您分享我们这两天遇到的OCS问题. 阿里云OCS(Open Cache Service)是 ...
随机推荐
- linux下载时提示请尝试移除磁盘中不需要的文件并重试,或者保存到其他位置
因为我是用虚拟机装的linux,所以当时就分配了20G硬盘,下载了几个应用后再下载就提示我这个了.一开始我还以为是因为下载链接的问题,后来才知道原来是因为/tmp的满了. 然后我输入以下连个命令就能正 ...
- 以setTimeout来聊聊Event Loop
平时的工作中,也许你会经常用到setTimeout这个方法,可是你真的了解setTimeout吗?本文想通过总结setTimeout的用法,顺便来探索javascript里面的事件执行机制. setT ...
- HQL查询——查询返回对象类型分析
关于HQL查询,我们可以结合hibernate的API文档,重点围绕org.hibernate.Query接口,分析其方法,此接口的实例对象是通过通过session.对象的creatQuery(Str ...
- JS排序算法
1.冒泡排序 冒泡算法是比较相邻的两项,如果前者比后者大,就交换他们. 假设一共有n项,那么一共需要n-1趟,第一趟需要交换n-1次,但是第一趟结束后,最后一项基本确定就是最大项了,所以第二次需要交换 ...
- Vue2.0音乐播放器
学习了几周的vuejs,学习的过程中做了一个音乐播放器WebApp (顺便听听音乐~) ,过程中也有借鉴过别人做的,感觉受益匪浅 链接 项目在线地址 : 音乐播放器 github : https:// ...
- 使用Visual Studio 2017作为Linux C++开发工具
Visual Studio 2017 微软的宇宙第一IDE Visual Studio 2017正式版出来了,地址是:https://www.visualstudio.com/vs/whatsnew/ ...
- LINQ笔记
LINQ概述 语言集成查询(Language intergrated Query,LINQ)在C#编程语言中集成了查询语法. 可以使用相同的语法访问不同的数据源 提供了不同数据源的抽象层,所有可以使用 ...
- Sublime Text 3常用插件安装(持续更新)
首先声明一下,小编是做后台开发出身,但是总是想捣鼓一些小的网站出来,可能是完美心作祟,感觉前端这边不能差事,所以就自己上了,一开始是用eclipse来开发的,具体原因忘了,也不知道怎么就开始用Subl ...
- 用Angular2+Express快速搭建博客
1. 写在前面 昨天花了1天的时间把自己的博客从以前的Express换成了Angular2+Express,遂记录于此.博客Demo在这里,你也可以点击这里查看完整代码. 第一次使用Angular2, ...
- 一个想法照进现实-《IT连》创业项目:关于团队组建
前言: 从上一篇<三天的风投对接活动内幕分享>归来后,从中领悟了不少内涵. 之后暂停了找钱的想法,这些天也拒绝了不少想要参与众筹的同学. 目前主要精力放在以下三件事: 1:重新规划顶层设计 ...