找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4711

积分

0

好友

609

主题
发表于 2 小时前 | 查看: 6| 回复: 0

开发应用程序久了,总想刨根问底,尤其对一些有公共答案的问题。很多答案大家都能说上几句,但追根究底,却解释不清。凡事都有为什么,用数字说明问题往往最直观。

本文主要想探究一下连接数据库的细节,尤其是在 Web 应用中要使用数据库连接池,以免每次发送请求都重新建立一次连接。对于这个问题,答案基本一致:建立数据库连接很耗时。但这个耗时到底是多少?又分别在哪些阶段产生?

本文以连接 MySQL 数据库为例,因为 MySQL 数据库是开源的,通信协议也是公开的,所以能够详细拆解连接建立的全过程。

在本文中,资源消耗分析主要集中在网络上。当然,资源也包括内存、CPU 等计算资源。代码使用 Java 编写,但不能排除编程语言本身也会带来一定影响。

先看一段最简单的 Java 建连代码:

Class.forName("com.mysql.jdbc.Driver");

String name = "xttblog2";
String password = "123456";
String url = "jdbc:mysql://172.16.100.131:3306/xttblog2";
Connection conn = DriverManager.getConnection(url, name, password);
// 之后程序终止,连接被强制关闭

接着用 Wireshark 抓包,分析整个连接的建立过程:

Wireshark 抓包:MySQL 连接建立过程

从抓包结果可以看到,MySQL 的通信协议基于 TCP,并且是二进制协议,而不是类似 HTTP 的文本协议。连接建立过程可以拆成三步:

  • 第 1 步:通过三次握手建立 TCP 连接;
  • 第 2 步:服务器向客户端下发「握手信息」,客户端响应该握手消息;
  • 第 3 步:客户端发送认证包,验证用户身份;验证通过后,服务器返回 OK 响应,之后才开始执行命令。

用户验证通过后,还会进行连接变量设置,比如字符集、是否自动提交事务等,期间会有多次数据交互。完成这些步骤后,才会执行真正的查询和更新操作。

本次测试只用 5 行代码建立连接,随后没有通过该连接执行任何操作。程序结束后,连接不是通过 Connection.close() 关闭,而是随着进程终止被异常断开,所以最后出现了 TCP 的 RST 报文。由于没有设置任何额外连接属性,设置属性阶段耗时可以认为是最少的;但驱动仍会默认设置字符集、事务自动提交等,具体取决于驱动实现。即便这样,统计信息显示:排除最后不需要服务器响应的 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();

这样情况会发生变化,主要体现在连接断开阶段:

Wireshark 抓包:MySQL 连接关闭过程

  • 第 1 步:客户端发送关闭连接请求,无需等待服务端响应;
  • 第 2 步:通过 TCP 四次挥手断开连接。

这次完整走完「建立连接 → 关闭连接」全过程,耗时:

747.284311 - 747.100954 = 0.183357s = 183.357ms

这里同样受网络状况影响,虽然比上面的 225ms 略少,但也接近 200ms 级别。

再做一个简单换算:假设一个日活 2 万的网站,每个用户每天只发 5 个请求,那么一天就有 10 万个请求。如果每次建连耗时按 150ms 保守计算,仅建立数据库连接一天就要耗费:

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

也就是说,每天光建立数据库连接就可能花掉 4 个小时。所以数据库连接池不是“要不要用”,而是必须用。并且随着日活上升,单靠连接池也不够,还要结合缓存、SQL 预编译、负载均衡等手段。

本文的核心结论只有一个:数据库连接真的很耗时,不要频繁建立连接。

来源:blog.csdn.net/lmy86263/article/details/76165714




上一篇:苹果真正的AI杀手锏不是Siri,是重回企业服务器搞M8 Ultra本地推理
下一篇:盘点 Lombok 的几个冷门注解:@Delegate、@Cleanup、@With 用法解析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-9-30 05:57 , Processed in 0.690355 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表