资讯详情

面试官:为什么数据库连接很消耗资源?我竟然答不上来。。一下懵了

在开发应用程序很长一段时间后,我总是想问问题的根源,特别是对于一些有公共答案的问题。每个人都可以解释,但最终,都无法解释。一切都有原因,用数字来解释问题是最直观的。

本文主要探讨连接数据库的细节,特别是在 Web 应用程序中应使用数据库连接池,以免每次发送请求时重新建立连接。

对于这个问题,答案是一致的。建立数据库连接需要很多时间,但是需要多少时间,需要多少时间?

本文以连接 MySQL 以数据库为例,因为 MySQL 数据库是开源的,其通信协议是开放的,因此我们可以详细分析建立连接的整个过程。

另外,MySQL 整理了一系列面试题和答案,微信搜索Java技术栈,后台发送面试,可在线阅读。

消耗资源的分析主要集中在网络上,当然,资源也包括内存,CPU 使用编程语言等计算资源 Java,但不排除编程语言也会有一定的影响。

首先看连接数据库。 Java 代码如下:

Class.forName("com.mysql.jdbc.Driver");  String name = "shine_user"; String password = "123"; String url = "jdbc:mysql://172.16.100.131:3306/clever_mg_test"; Connection conn = DriverManager.getConnection(url, name, password); // 程序终止后,强制关闭连接

然后通过「Wireshark」整个连接的建立过程分析如下:

*Wireshark 抓包*

从上图中显示的连接过程中可以看出 MySQL 的通信协议是基于 TCP 传输协议,该协议为二进制协议,相似 HTTP 文本协议。

建立连接的过程如下:

  • 建立 TCP 通过三次握手实现连接。
  • 服务器发送给客户端「握手信息」,客户端响应该握手消息。
  • 客户端「发送认证包」,用于用户验证,验证成功后,服务器返回 OK 响应,然后开始执行命令。

用户验证成功后,会设置一些连接变量,如字符集、是否自动提交等,并且会有多个数据交互。在完成这些步骤后,将执行真实的数据查询和更新。

只用于本文的测试 5 行代码建立连接,但没有通过连接执行任何操作,所以程序执行后,连接不是通过 Connection.close() 关闭,但由于程序执行完成,过程终止,与数据库的连接异常关闭,最终会出现 TCP 的 RST 报文。

在这个最简单的代码中,没有额外的连接属性,所以设置属性的时间可以被认为是最少的(事实上,虽然我们没有设置任何属性,但驱动器仍然设置字符集、自动提交等,这取决于具体的驱动实现),所以整个连接可以被认为是最少的。

但从统计信息中可以看出,不包括最终信息 TCP 的 RST 报文时(因为报文不需要服务器返回任何响应),但仍需在客户端和服务器之间往返「7」次,「也就是说,如果连接完成,可以认为数据至少需要在客户端和服务器之间往返 7 次」。

从时间上看,从开始 TCP 三次握手,直到最终连接被强制断开(不包括最后一次) RST 报文),总费用:

10.416042 - 10.190799 = 0.225243s = 225.243ms

这意味着需要建立数据库连接 225ms,当然,这仍然可以被认为是最少的「网络状况、数据库服务器性能和应用代码是否高效可能会影响所花费的时间」,但这只是最简单的例子,足以解释问题!

由于上述程序异常终止,在正常应用程序中,通常通过连接关闭 Connection.close() 完成的。

代码如下:

Class.forName("com.mysql.jdbc.Driver");  String name = "shine_user"; String password = "123"; String url = "jdbc:mysql://172.16.100.131:3306/clever_mg_test"; Connection conn = DriverManager.getConnection(url, name, password); conn.close();

在这种情况下,情况发生了变化,主要体现在与数据库连接的断开,如上图所示:

  • 此时处于 MySQL 在通信协议阶段,客户端发送关闭连接请求,无需等待服务端响应。
  • TCP 断开连接,4 挥手完成连接断开。

从数据库连接的建立到关闭,整个过程已经完全完成:

747.284311 - 747.100954 = 0.183357s = 183.357ms

与上述情况相比,这里也可能有网络状况的影响 225ms 少了,但也几乎达到了 200ms 的级别。

所以问题来了,想象一下这个场景,对于日常生活 2 对于万网站,假设每个用户只会发送 5 一个请求,那么一天就是 10 万个请求。

我们保守地计算数据库连接的建立 150ms 嗯,在一天内建立数据库连接需要时间(不包括执行查询和更新操作):

100000 * 150ms = 15000000ms = 15000s = 250min = 4.17h

也就是说,每天建立数据库连接的时间已经到了「4 个小时」,所以数据库连接池是必要的。

当日常生活增加时,仅使用数据库连接池并不能完全保证您的服务能够正常运行,还需要考虑其他解决方案。

例如:

  • 缓存
  • SQL 的预编译
  • 负载均衡
  • ……

当然,这不是本文的主要内容。本文只有一个核心思想需要阐述。数据库连接真的很耗时,所以不要经常建立连接。

版权声明:本文为CSDN博主「lmy86263」遵循原创文章CC 4.0 BY-SA版权协议,请附上原始来源链接和本声明。 原文链接:https://blog.csdn.net/lmy86263/article/details/76165714

1.1,000 道 Java整理面试题和答案(2022年最新版)

2.劲爆!Java 协程来了。

3.Spring Boot 2.x 教程,太全了!

4.不要写满屏爆炸类,试试装饰模式,这是优雅的方式!

5.《Java开发手册(嵩山版)最新发布,快速下载!

感觉不错,别忘了点赞。 转发哦!

标签: mg643183连接器mg642570连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台