1.概述转载为什么数据库连接很消耗资源开发应用程序久了总想刨根问底尤其对一些有公共答案的问题。大家都能解释但是追根究底都解释不清。凡是都有为什么而且用数字说明问题是最直观的。本文主要想探究一下连接数据库的细节尤其是在Web应用中要使用数据库来连接池以免每次发送一次请求就重新建立一次连接。对于这个问题答案都是一致的建立数据库连接很耗时但是这个耗时是都多少呢又是分别在哪些方面产生的耗时呢本文以连接MySQL数据库为例因为MySQL数据库是开源的其通信协议是公开的所以我们能够详细分析建立连接的整个过程。在本文中消耗资源的分析主要集中在网络上当然资源也包括内存、CPU等计算资源使用的编程语言是Java但是不排除编程语言也会有一定的影响。首先先看一下连接数据库的Java代码如下Class.forName(com.mysql.jdbc.Driver);Stringnamexttblog2;Stringpassword123456;Stringurljdbc:mysql://172.16.100.131:3306/xttblog2;ConnectionconnDriverManager.getConnection(url,name,password);// 之后程序终止连接被强制关闭然后通过「Wireshark」 分析整个连接的建立过程如下在上图中显示的连接过程中可以看出MySQL的通信协议是基于TCP传输协议的而且该协议是二进制协议不是类似于HTTP的文本协议其中建立连接的过程具体如下第1步建立TCP连接通过三次握手实现第2步服务器发送给客户端「握手信息」 客户端响应该握手消息第3步客户端「发送认证包」 用于用户验证验证成功后服务器返回OK响应之后开始执行命令用户验证成功之后会进行一些连接变量的设置比如字符集、是否自动提交事务等其间会有多次数据的交互。完成了这些步骤后才会执行真正的数据查询和更新等操作。在本文的测试中只用了5行代码来建立连接但是并没有通过该连接去执行任何操作所以在程序执行完毕之后连接不是通过Connection.close()关闭的而是由于程序执行完毕导致进程终止造成与数据库的连接异常关闭所以最后会出现TCP的RST报文。在这个最简单的代码中没有设置任何额外的连接属性所以在设置属性上占用的时间可以认为是最少的其实虽然我们没有设置任何属性但是驱动仍然设置了字符集、事务自动提交等这取决于具体的驱动实现所以整个连接所使用的时间可以认为是最少的。但从统计信息中可以看出在不包括最后TCP的RST 报文时因为该报文不需要服务器返回任何响应但是其中仍需在客户端和服务器之间进行往返「7」 次「也就是说完成一次连接可以认为数据在客户端和服务器之间需要至少往返7次」 从时间上来看从开始TCP的三次握手到最终连接强制断开为止不包括最后的RST报文总共花费了10.416042-10.1907990.225243s**225.243ms**这意味着建立一次数据库连接需要225ms而这还是还可以认为是最少的当然「花费的时间可能受到网络状况、数据库服务器性能以及应用代码是否高效的影响」 但是这里只是一个最简单的例子已经足够说明问题了由于上面是程序异常终止了但是在正常的应用程序中连接的关闭一般都是通过Connection.close()完成的代码如下Class.forName(com.mysql.jdbc.Driver);Stringnameshine_user;Stringpassword123;Stringurljdbc:mysql://172.16.100.131:3306/clever_mg_test;ConnectionconnDriverManager.getConnection(url,name,password);conn.close();这样的话情况发生了变化主要体现在与数据库连接的断开如下图第1步此时处于MySQL通信协议阶段客户端发送关闭连接请求而且不用等待服务端的响应第2步TCP断开连接4次挥手完成连接断开这里是完整地完成了从数据库连接的建立到关闭整个过程花费了747.284311-747.1009540.183357s183.357ms这里可能也有网络状况的影响比上述的225ms少了但是也几乎达到了200ms的级别。那么问题来了想象一下这个场景对于一个日活2万的网站来说假设每个用户只会发送5个请求那么一天就是10万个请求对于建立数据库连接我们保守一点计算为150ms好了那么一天当中花费在建立数据库连接的时间有还不包括执行查询和更新操作100000*150ms15000000ms15000s250min4.17h也就说每天花费在建立数据库连接上的时间已经达到「4个小时」 所以说数据库连接池是必须的嘛而且当日活增加时单单使用数据库连接池也不能完全保证你的服务能够正常运行还需要考虑其他的解决方案缓存SQL的预编译 负载均衡 ……当然这不是本文的主要内容「本文想要阐述的核心思想只有一个数据库连接真的很耗时所以不要频繁的建立连接」 。
阅读完成 · 觉得有帮助?