本文转载自微信公众号《精益码农》,作者小马甲。转载本文请联系精益码农公众号。一般我们在项目中会用到1或2个数据库连接配置。同程艺龙的数据库连接配置都汇集到一个统一的配置中心,由DBA统一维护。业务方通过某个配置字符串得到的是开箱即??用的Connection对象。DBA可以在不侵入业务端的情况下为业务端切换备份数据库,然后DBA要求必须立即清空旧的连接池。那么问题来了:我可以立即清空.NET连接池吗?请注意,我使用清空而不是释放连接。如果有同学不知道DBA请求的目的,我说几句:当应用不再使用旧的连接时,理论上你的连接池应该彻底清空,因为简单的释放连接只会使连接连接池中的Connection处于Sleep状态,物理连接仍会保持一小段时间。这段时间其实是不必要的占用,影响了旧连接数据库的吞吐量。连接池知识背景在回答这个问题之前,我们先来学习一下.NET数据库连接池。一、.NET数据库连接池的背景。数据库连接是一个耗时的行为。大多数应用程序只使用一个或多个数据库连接。为了最小化打开连接的成本,ado.net使用了一种称为连接池的方法。优化技术。2..NET数据库连接池的性能数据库连接池减少了必须打开新连接的次数,并且池程序保持与数据库的物理连接。通过为每个特定的连接配置保留一组活动的连接对象来管理连接。每当应用程序试图打开一个连接时,池程序会在池中寻找一个可用的连接,如果有则返回给调用者;当应用程序关闭连接对象时,池程序会将连接对象返回到池中(Sleep),这个连接可以在下一次Open调用中被重用。看黑板,下面是本次的重点:3..NET是如何形成数据库连接池的?只能池化相同的连接配置,.NET为不同的配置维护不同的连接池。相同的配置仅限于:相同的进程、相同的连接字符串、相同的连接字符串键序。(连接字符串提供的关键字顺序也会分配到不同的池中)。连接池中的可用连接数由连接字符串MaxPoolSize决定。在一个应用程序中,有如下代码:InitialCatalog=pubs")){connection.Open();//PoolBiscreatedbecausetheconnectionstringsdiffer.}using(SqlConnectionconnection=newSqlConnection("IntegratedSecurity=SSPI;InitialCatalog=Northwind")){connection.Open();//创建的connectionstringmatchespoolA.}上面三连接对象,但只形成了两个数据库连接池。还是上面的代码,如果有两个相同的应用,理论上就形成了四个数据库连接池。4、连接池中的连接什么时候被移除?连接池中的连接空闲4-8分钟,池程序会移除该连接。当应用下线时,连接池直接被清空。如何主动清理.NET连接池有了以上的知识背景,我们再来回顾一下DBA的需求。切换数据库连接配置时,清除原来的连接池。.NET提供了ClearAllPools和ClearPool静态方法来清除连接池。ClearAllPools:ClearallconnectionpoolsassociatedwiththisDBProviderClearPool(DBConnectionconn)清除与这个连接对象关联的连接池很明显,我们这次要用到ClearPool(DBConnectionconn)方法。不练习不验证,光说不说不是我的作风。天锤压测/queryapi生成连接池,包含大量连接对象;在适当的时候,调用/clearpoolapi来清除连接池。publicclassMySqlController:Controller{//GET:MySql[Route("query")]publicstringIndex(){vars="UserID=teinfra_neo_netreplay;Password=123456;DataBase=teinfra_neo_netreplay;Server=10.100.41.196;Port=3980;MinPoolSize=1;MaxPoolSize=28;CharSet=utf8;";using(varconn=newMySqlConnection(s)){varcomm=conn.CreateCommand();comm.CommandText="selectcount(*)fromusertest;";conn.Open();varret=comm.ExecuteScalar();comm.CommandText="selectcount(*)frominformation_schema.PROCESSLISTWHEREHOSTlike'10.22.12.245%';";varlen=comm.ExecuteScalar();return$"查询结果:{ret},查看当前连接池方式连接对象数:{len}";};}[Route("clearpool")]publicstringSwitch(){vars="UserID=teinfra_neo_netreplay;Password=123456;DataBase=teinfra_neo_netreplay;Server=10.100.41.196;Port=第3980章{康恩。Open();varcomm=conn.CreateCommand();comm.CommandText="selectcount(*)frominformation_schema.PROCESSLISTWHEREHOSTlike'10.22.12.245%';";varlen=comm.ExecuteScalar();return$"连接池已经清空之前,Thisqueryconnectionpoolhas{v1}connectionobjects";}}}1.压测产生大量连接对象2.mysql数据库与mysql查询命令的连接数:(host为的IPWeb服务器):select*frominformation_schema.PROCESSLISTWHEREHOSTlike'10.22.12.245%';3、调用/clearpoolapi清除连接池宾果,清除连接池的理论已经验证.NET数据库连接池属于编程语言的范畴。连接池维护物理连接的定义。目前连接数的方式就是按照这个思路改造祖传代码,.NET数据采集组件SDK已经满足了DBA的要求。希望本文的设计思考、理论+论证对读者有所帮助。距离上一篇文章发表已经一个多月了。再次感谢不离不弃的5000+读者。参考链接【1】sql连接池(ado.net):https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling
