详解.NET数据库连接池
作者:有态度的马甲 发布时间:2024-01-20 16:05:59
一般我们的项目中会使用1到2个数据库连接配置,同程艺龙的数据库连接配置被收拢到统一的配置中心,由DBA统一配置和维护,业务方通过某个字符串配置拿到的是Connection对象。
DBA能在对业务方无侵入的情况下,给业务方切换备份数据库,之后DBA要求旧连接池必须立即被清空, 那么问题来了: dotnet能不能立即清空连接池? 注意我用得是清空,而不是释放连接。
如果有同学不知道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. 经过压测工具
2. mysql数据库对比
mysql的连接数查询命令, (host是web服务器IP):
select * from information_schema.PROCESSLIST WHERE HOST like '10.22.12.245%';
3. 调用/clearpoolapi,清空连接池
bingo,清空连接池的理论得到验证。
干货旁白
这是我在同程艺龙最近爬的比较深的坑位,
我从本次实践中理解了.NET数据库连接池的定义方式、并配套掌握了DBProvider 对于.net连接数的查询定位方式。
对祖传代码的改造,.NET数据获取组件SDK 确实提高了原数据库的吞吐量。
希望本文设计考量、理论+论证的行文思路对于读者有所帮助, 再次感谢有心读者取关、再关注。
来源:https://www.cnblogs.com/JulianHuang/p/15151213.html


猜你喜欢
- 写一个循环删除的过程。 create or replace procedure delBigTab(p_TableName in varch
- 为了使一个MySQL系统安全,强烈要求你考虑下列建议……当你连接一个MySQL服务器时,你通常应
- 一、TensorFlow常规模型加载方法保存模型tf.train.Saver()类,.save(sess, ckpt文件目录)方法参数名称功
- 标准库的fnmatch库专门用来进行文件名匹配,支持使用通配符进行字符串匹配。1、fnmatch:判断文件名是否符合特定的模式;2、fnma
- 如下图,我们在做图片logo列表的时候通常是用li标签来实现。html:<ul class="logolist&q
- Django 开发项目是很快的,有多快?看完本篇文章,你就知道了。安装 Django前提条件:已安装 Python。Django 使用 pi
- pyppeteer介绍Pyppeteer之前先说一下Puppeteer,Puppeteer是谷歌出品的一款基于Node.js开发的一款工具,
- 使用re, urllib, threading多线程抓取天涯帖子内容,设置url为需抓取的天涯帖子的第一页,设置file_name为下载后的
- Vision Transformer(VIT)Vision Transformer(ViT)是一种新兴的图像分类模型,它使用了类似于自然语言
- 接触pytorch一天,发现pytorch上手的确比TensorFlow更快。可以更方便地实现用预训练的网络提特征。以下是提取一张jpg图像
- python3 在服务器上打印资产信息pip3 install prettytableurl 为 资产信息接口地址,返回为json信息。#
- write2vin 的 PPT原文路宛兮写的简介:本文解释了以下问题: 1.什么是用户体验? 2.谁发明了这个术语?他想表达什么意思? 3.
- 实例如下所示:import numpy as npa1 = np.array([1,2,3,4],dtype=np.complex128)p
- 本文要实现的功能是:根据下拉列表的选项将数据库中对应的内容显示在页面,选定要排除的选项后,提交剩余的选项到数据库。为了方便前后台交互,利用了
- public function json_product_list($where, $order){ global $_M; $this-&
- 不知道您是否留意了,浏览本站时,浏览器右下角有一个标着top的黑色直角三角形,可以点击它返回到正在浏览的网页页眉。当滚动网页时,它的位置一直
- 如下所示:list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] slice = random.sample(list
- 最简单的php语句把数据库*.sql文件导入数据库 $sql=file_get_contents("text.sql")
- 喜欢用 Python 做项目的小伙伴不免会遇到这种情况:做图表时,用哪种好看又实用的可视化工具包呢?之前文章里出现过漂亮的图表时,也总有读者
- 每次要显示图像阵列的时候,使用自带的 matplotlib 或者cv2 都要设置一大堆东西,subplot,fig等等,突然想起 可以利用n