你认为的.NET数据库连接池,真的是全部吗?

news2025/1/16 3:38:27

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

DBA能在对业务方无侵入的情况下,让大规模微服务实例切换数据库连接,之后DBA要求对旧数据库的连接必须立即被清空, 那么问题来了: **dotnet程序怎么清空数据库连接?

如果有同学不知道DBA做这个要求的目的,那我啰嗦一下:
应用程序不再使用旧连接时,理论上你的连接池要被完全清空,因为单纯的释放连接,只会让连接池中的Connection处于Sleep状态,依旧维持了短时间的物理连接,这个短时间其实是不必要的占用,影响了旧连接数据库的吞吐量。

前置知识背景

回答这个问题之前, 我们还是先梳理一下:

  • dotnet进程, 数据库进程;
  • 两者都存在连接池,.NET数据库连接池, 数据库连接池。

.net能直接维护的是 .net数据库连接池, 本次我们通过清空.NET数据库连接池,清理应用进程与具体数据库的物理连接

1. 先掌握.NET数据库连接池

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

.NET 数据库连接池程序维护了数据库物理连接,
通过为每个特定的连接配置保持一组活动的连接对象来管理连接。

每当应用程序尝试Open连接,池程序就会在池中找到可用的连接,如果有则返回给调用者;
应用程序Close连接对象时,池程序将连接对象返回到池中(Sleep), 这个连接可以在下一次Open调用中重用。

2. .NET数据库连接池是如何建立的?

在一个进程中,相同的连接配置才能被池化,.NET为不同连接配置维护了不同的连接池。

进程级别、  
连接字符串相同、  
连接字符串关键key顺序相同。  
(同一连接提供的关键字顺序不同将被分到不同的池)。

池初次建立的时候,创建了最小数量的connection对象,为满足后续的业务需求,池会渐增connection对象,直至达到Max Pool Size最大连接数(默认是100)。

后续请求如果面临.NET数据库连接池满的情况,将会进队列等待 ,超时15s抛出异常。

在一个应用程序中,有如下代码:

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对象,但是只形成了两个数据库连接池

还是以上代码,如果有两个相同的应用程序,理论上就形成了四个数据库连接池。

3. 连接池中的连接什么时候被移除?

数据库连接对象,在被释放或者关闭的时候,会回收进连接池。

We strongly recommend that you always close the connection when you are finished using it so that the connection will be returned to the pool. You can do this using either the Close or Dispose methods of the Connection object, or by opening all connections inside a using statement in C#.

连接池中的连接空闲4-8 分钟,池程序会移除这个连接。

应用程序关闭,连接池直接被清空。


.NET 如何清空.NET连接池?

有了以上知识背景

我们再来回顾一下DBA的要求,切换原连接配置的时候,清空对原数据库的连接。

.NET这边只能操作.NET数据库连接池。

.NET提供ClearAllPools、ClearPool静态方法用于清空连接池, 目前看sqlserver,mysql客户端库均实现了这两个方法。

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

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

ClearAllPools() 过于暴力,直接清空了此时与这个provider相关的连接池, 可能对于其他应用进程的数据库连接造成损流,

要使用细粒度的进程相关的 ClearPool(DBConnection conn) 方法, 本应用进程切换数据库连接之后,只清空与本次连接相关的.NET 数据库连接池。

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

天锤压测/queryapi 产生一个包含大量连接对象的连接池;
适当的时候,/clearpoolapi清空.NET连接池。

 using MySql.Data.MySqlClient;       // 引入MySql.Data.dll库文件  

 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数据库对比

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

3. 调用/clearpoolapi,清空.NET连接池, 进而直接影响 mysql数据库的物理连接。

bingo,清空.NET连接池===> 清理mysql数据库物理连接 的理论得到验证。

干货旁白

这是我在同程艺龙最近爬的比较深的坑位,
从本次实践中理解了.NET数据库连接池的定义方式、

清空进程级别.NET数据库连接池===> 清理该进程与数据库的物理连接。

对祖传代码的改造,.NET数据获取组件SDK 确实提高了原数据库的吞吐量。

希望本文设计考量、理论+论证的行文思路对于读者有所帮助, 再次感谢有心读者取关、再关注。

  • https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/connection-pooling

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/415740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第二周P9-P22

文章目录第三章 系统总线3.1、总线的基本概念一、为什么要用总线二、什么是总线三、总线上信息的传送四、总线结构的计算机举例1、单总线结构框图2、面向CPU的双总线结构框图3、以存储器为中心的双总线结构图3.2、总线的分类1、片内总线2、系统总线3、通信走线3.3、总线特性及性…

基于多目标粒子群优化算法的计及光伏波动性的主动配电网有功无功协调优化(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Vivado中ILA(集成逻辑分析仪)的使用

Vivado中ILA(集成逻辑分析仪)的使用一、写在前面二、ILA(Integrated Logic Analyzer)的使用2.1 ILA查找2.2 ILA配置2.2.1 General Options2.2.2 Probe Ports三、ILA调用四、ILA联调4.1 信号窗口4.2 波形窗口4.3 状态窗口4.4 设置窗口4.5 触发条件设置窗口…

Segment Anything论文详解(SAM)

论文名称:Segment Anything 论文地址:https://arxiv.org/abs/2304.02643 开源地址:https://github.com/facebookresearch/segment-anything demo地址:Segment Anything | Meta AI 主要贡献:开发一个可提示的图像分…

6.Java数组

数组 一、数组概述 1、什么是数组? 数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问它们。 2、数组的…

哈夫曼树和最小生成树

哈夫曼树 首先给我们一串权值,然后我们需要让这串权值组成一个树,然后当他的wpl最小 我们可以发现当他的小权值离根节点越远,大权值离根节点越近的时候,我们这个时候构建出来的树就是wpl最小的树,也就是我们说的哈夫曼…

c++之 类和对象

目录 1.类和对象的基本概念 1.c语言与c中的结构体 2.类的封装性 3.定义类 4.构造与析构 构造与析构的概念: 构造函数 析构函数 拷贝构造函数 c默认增加的函数 1.类和对象的基本概念 1.c语言与c中的结构体 我们知道在c语言里,我们是无法在结构体…

进程的开销比线程大在了哪里?

进程内部都有哪些数据? 为什么创建进程的成本很高? 这样的问题确实不好回答,除非你真正理解了进程和线程的原理,否则很容易掉入面试大坑。探究问题背后的原理,围绕面试题展开理论与实践知识的学习。真正理解进程和线…

centos7虚拟机下hbase的使用案例讲解

系列文章目录 centos7虚拟机在集群zookeeper上面配置hbase的具体操作步骤 centos7虚拟机配置集群时间同步的操作步骤_centos虚拟机时间同步 centos7配置zookeeper本地模式与集群模式的详细教程 卸载centos7自带的jdk的操作步骤_centos7 卸载java 虚拟机centos7配置Hadoop单…

如何用 Vitis HLS 实现 OpenCV 仿真

这篇文章的基础是《Windows上快速部署Vitis HLS OpenCV仿真库》,我们使用的版本是Vitis HLS 2022.2,其他版本BUG不清楚,目前已知2021版本有BUG,只能使用其他方式,本文不适合。 这次选择中值滤波这个常规算法作为演示算…

Springboot电脑商城项目

目录 系统概述与环境搭建 1 系统开发及运行环境 2 项目分析 3 创建数据库 4 创建Spring Initializr项目 5 配置并运行项目 6 导入前端项目 用户注册 1 用户-创建数据表 2 用户-创建实体类 3 用户-注册-持久层 4 用户-注册-业务层 5 用户-注册-控制器 6 用户-注册…

归并排序(递归实现)

上一次我们说了快排的其他版本,还有就是快排的非递归实现 这次我们就说一哈归并排序,归并排序也是很厉害的一种排序,而且归并排序的时间复杂度可以说成标准的O(n log n) 下面我们就来看一下归并排序 我们先来看一下什么是归并排序 假设我…

Scratch蓝桥杯实战训练 —— 巧解“韩信点兵”难题的五种方式

“韩信点兵”蓝桥杯问题描述: “蓝桥杯”中有一道有趣的 Scratch 编程题,题目要求为:韩信点兵 扩展知识: 这道题叫“中国余数定理”,又叫“孙子定理”,也叫“韩信点兵问题”,是我国古代数学智慧…

Faster-RCNN代码解读3:制作自己的数据加载器

Faster-RCNN代码解读3:制作自己的数据加载器 前言 ​ 因为最近打算尝试一下Faster-RCNN的复现,不要多想,我还没有厉害到可以一个人复现所有代码。所以,是参考别人的代码,进行自己的解读。 ​ 代码来自于B站的UP主&…

Node【三】Buffer 与 Stream

文章目录🌟前言🌟Buffer🌟 Buffer结构🌟 什么时候用Buffer🌟 Buffer的转换🌟 Buffer使用🌟 创建Buffer🌟 字符串转Buffer🌟 Buffer转字符串🌟 拼接Buffer&…

python 理解BN、LN、IN、GN归一化、分析torch.nn.LayerNorm()和torch.var()工作原理

目录 前言: 简言之BN、LN、IN、GN等归一化的区别: 批量归一化(Batch Normalization,BN) 优点 缺点 计算过程 层归一化(Layer Normalization,LN) 优点 计算过程 总结 分析torch.nn.LayerNorm()工作原理 分析torch.var(…

Vue2-黑马(十一)

目录: (1)vue2-联调准备 (2)vue2-登录实战-国际化 (3)vue2实战-登录-login-index.vue (1)vue2-联调准备 登录这个请求,并不是发给后台的,现在还…

浙大MBA提面申请材料的三六九等……

每年浙大MBA项目提前批面试申请的每个批次中都会有部分材料因为某些原因而被淘汰,无缘面试资格。考生们由最初的不理解到逐渐隐约的理解,行至今日也可以大体接受材料被刷这个结果,当然其中含有一部分面上资质背景还可以的考生,等到…

Faster-RCNN代码解读2:快速上手使用

Faster-RCNN代码解读2:快速上手使用 前言 ​ 因为最近打算尝试一下Faster-RCNN的复现,不要多想,我还没有厉害到可以一个人复现所有代码。所以,是参考别人的代码,进行自己的解读。 ​ 代码来自于B站的UP主(…

中国电子学会2023年03月份青少年软件编程Scratch图形化等级考试试卷四级真题(含答案)

2023-03 Scratch四级真题 分数:100 题数:24 测试时长:90min 一、单选题(共10题,共30分) 1.编写一段程序,从26个英文字母中,随机选出10个加入列表a。空白处应填入的代码是?(C&am…