在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一配置和维护,业务方通过某个字符串配置拿到的是Connection对象。 DBA能在对业务方无侵入的情况下,给业务方切换备份数据库,之后DBA要求旧连接池必须立即被清空, 那么问题来了: dotnet能不能立即清空连接池? 注意我用得是清空,而不是释放连接。
前置知识背景回答这个问题之前, 我们还是先研究一下.NET数据库连接池。 1. .NET数据库连接池的背景数据库连接是一个耗时的行为,大多数应用程序只使用1到几种数据库连接,为了最小化打开连接的成本,ado.net使用了一种称为连接池的优化技术。 2. .NET 数据库连接池的表现数据库连接池减少了必须打开新连接的次数,池程序维护了数据库物理连接。 通过为每个特定的连接配置保持一组活动的连接对象来管理连接。 每当应用程序尝试Open连接,池程序就会在池中找到可用的连接,如果有则返回给调用者; 看黑板,下面是这次的重点: 3. .NET是如何形成数据库连接池的?只有相同的连接配置才能被池化,.NET为不同的配置维护了不同的连接池。 相同的配置限制为: 连接池中的可用连接的数量由连接字符串Max Pool Size决定。 在一个应用程序中,有如下代码: 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. } 上面创建了三个Connection对象,但是只形成了两个数据库连接池。 还是以上代码,如果有两个相同的应用程序,理论上就形成了四个数据库连接池。 4. 连接池中的连接什么时候被移除?连接池中的连接空闲4-8 分钟,池程序会移除这个连接。 应用程序下线,连接池直接被清空。 .NET 如何清空连接池?有了以上知识背景 我们再来回顾一下 DBA的要求,切换原连接配置的时候,清空连接池。 我从官方文档找到
很明显,我们这次要使用ClearPool(DBConnection conn) 方法。 光说不练不验证,不是我的风格。 天锤压测/queryapi 产生一个包含大量连接对象的连接池; 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 $"查询结果:{ret} ,顺便查一下当前连接池的连接对象个数: {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 $"之前已经清空连接池, 此次查询连接池有 {v1} 个连接对象"; } } } 1. 经过压测工具2. mysql数据库对比
3. 调用/clearpoolapi,清空连接池bingo,清空连接池的理论得到验证。 干货旁白这是我在同程艺龙最近爬的比较深的坑位, 对祖传代码的改造,.NET数据获取组件SDK 确实提高了原数据库的吞吐量。 希望本文设计考量、理论+论证的行文思路对于读者有所帮助, 再次感谢有心读者取关、再关注。 到此这篇关于详解.NET数据库连接池的文章就介绍到这了,更多相关.NET数据库连接池内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论