如何主动清空.NET数据库连接池?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一维护,业务方通过某个配置字符串拿到的是开箱即用的Connection对象。

一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一维护,业务方通过某个配置字符串拿到的是开箱即用的Connection对象


2311d7448b66129a1f37047c56cb3cf5.png


DBA能在对业务方无侵入的情况下,给业务方切换备份数据库,之后DBA要求旧连接池必须立即被清空。


那么问题来了: 不能立即清空.NET连接池?注意我用得是清空,而不是释放连接。


如果有同学不知道DBA做这个要求的目的,那我啰嗦一下:


应用程序不再使用旧连接时,理论上你的连接池要被完全清空,因为单纯的释放连接,只会让连接池中的Connection处于Sleep状态,依旧维持了短时间的物理连接这个短时间其实是不必要的占用,影响了旧连接数据库的吞吐量。


连接池知识背景


回答这个问题之前, 我们还是先研究一下.NET数据库连接池。


1. .NET数据库连接池的背景


数据库连接是一个耗时的行为,大多数应用程序只使用1到几种数据库连接,为了最小化打开连接的成本,ado.net使用了一种称为连接池的优化技术。


2. .NET 数据库连接池的表现


数据库连接池减少了必须打开新连接的次数,池程序维护了数据库物理连接。


通过为每个特定的连接配置保持一组活动的连接对象来管理连接。


每当应用程序尝试Open连接,池程序就会在池中找到可用的连接,如果有则返回给调用者;


应用程序Close连接对象时,池程序将连接对象返回到池中(Sleep), 这个连接可以在下一次Open调用中重用。


看黑板,下面是这次的重点:


3. .NET是如何形成数据库连接池的?


只有相同的连接配置才能被池化,.NET为不同的配置维护了不同的连接池。


相同的配置限制为:

进程相同、
连接字符串相同、

连接字符串关键key顺序相同。

(连接字符串提供的关键字顺序不同也将被分到不同的池)。


连接池中的可用连接的数量由连接字符串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的要求,切换数据库连接配置的时候,清空原连接池。


.NET提供了 ClearAllPools、ClearPool静态方法用于清空连接池。


ClearAllPools:      清空与这个DBProvider相关的所有连接池


ClearPool(DBConnection conn)      清空与这个连接对象相关的连接池


很明显,我们这次要使用ClearPool(DBConnection conn) 方法。


光说不练不验证,不是我的风格。


天锤压测/queryapi 产生一个包含大量连接对象的连接池;


适当的时候,调用/clearpoolapi清空连接池。


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.压测产生大量连接对象


8d0b5e8166059dc2a79566e7c4bb9798.png


2. mysql数据库对比


db0a55430860259859cec9669689e7ff.png


mysql的连接数查询命令: (host是web服务器IP):
select * from information_schema.PROCESSLIST WHERE HOST like '10.22.12.245%' ;

 

3.  调用/clearpoolapi,清空连接池


8cc5a5942ba99c9e432b412c7818d86e.png


bingo,清空连接池的理论得到验证。


旁白


这是我在同程艺龙最近爬的比较深的坑位, 在本次实践中我们了解到:


.NET 数据库连接池属编程语言范畴,连接池维护了物理连接


.NET数据库连接池的定义方式:(同一进程、同一连接字符串、同一连接字符串关键key顺序一致) 被划到一个池


DB客户端查询当前连接数的方式


根据这个思路改造祖传代码,.NET数据获取组件SDK 已经满足了DBA的要求。


希望本文设计考量、理论+论证的行文思路对读者有所帮助。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
SQL 数据库 C#
C# .NET面试系列十一:数据库SQL查询(附建表语句)
#### 第1题 用一条 SQL 语句 查询出每门课都大于80 分的学生姓名 建表语句: ```sql create table tableA ( name varchar(10), kecheng varchar(10), fenshu int(11) ) DEFAULT CHARSET = 'utf8'; ``` 插入数据 ```sql insert into tableA values ('张三', '语文', 81); insert into tableA values ('张三', '数学', 75); insert into tableA values ('李四',
168 2
C# .NET面试系列十一:数据库SQL查询(附建表语句)
|
7月前
|
开发框架 Oracle 关系型数据库
ASP.NET实验室LIS系统源码 Oracle数据库
LIS是HIS的一个组成部分,通过与HIS的无缝连接可以共享HIS中的信息资源,使检验科能与门诊部、住院部、财务科和临床科室等全院各部门之间协同工作。 
85 4
|
7月前
|
SQL 数据库连接 数据库
你不知道ADo.Net中操作数据库的步骤【超详细整理】
你不知道ADo.Net中操作数据库的步骤【超详细整理】
|
2月前
|
SQL 开发框架 .NET
ASP.NET连接SQL数据库:详细步骤与最佳实践指南ali01n.xinmi1009fan.com
随着Web开发技术的不断进步,ASP.NET已成为一种非常流行的Web应用程序开发框架。在ASP.NET项目中,我们经常需要与数据库进行交互,特别是SQL数据库。本文将详细介绍如何在ASP.NET项目中连接SQL数据库,并提供最佳实践指南以确保开发过程的稳定性和效率。一、准备工作在开始之前,请确保您
286 3
|
4月前
|
SQL 开发框架 数据库
".NET开发者的超能力:AgileEAS.NET ORM带你穿越数据库的迷宫,让数据操作变得轻松又神奇!"
【8月更文挑战第16天】AgileEAS.NET是面向.NET平台的企业应用开发框架,核心功能包括数据关系映射(ORM),允许以面向对象方式操作数据库,无需编写复杂SQL。通过继承`AgileEAS.Data.Entity`创建实体类对应数据库表,利用ORM简化数据访问层编码。支持基本的CRUD操作及复杂查询如条件筛选、排序和分页,并可通过导航属性实现多表关联。此外,提供了事务管理功能确保数据一致性。AgileEAS.NET的ORM简化了数据库操作,提升了开发效率和代码可维护性。
58 5
|
1月前
|
数据库 C# 开发者
ADO.NET连接到南大通用GBase 8s数据库
ADO.NET连接到南大通用GBase 8s数据库
|
1月前
|
存储 缓存 NoSQL
2款使用.NET开发的数据库系统
2款使用.NET开发的数据库系统
|
1月前
|
数据库连接 数据库 C#
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
|
1月前
|
数据库连接 数据库 C#
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(下)
本文接续前文,深入讲解了在Windows环境下使用C#和ADO.NET操作南大通用GBase 8s数据库的方法。通过Visual Studio 2022创建项目,添加GBase 8s的DLL引用,并提供了详细的C#代码示例,涵盖数据库连接、表的创建与修改、数据的增删查改等操作,旨在帮助开发者提高数据库管理效率。
|
2月前
|
存储 NoSQL API
.NET NoSQL 嵌入式数据库 LiteDB 使用教程
.NET NoSQL 嵌入式数据库 LiteDB 使用教程~