为什么数据库连接很消耗资源?

1背景

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

本文主要想探究一下连接数据库的细节,尤其是在 Web 应用中要使用数据库来连接池,以免每次发送一次请求就重新建立一次连接。

对于这个问题,答案都是一致的,建立数据库连接很耗时,但是这个耗时是都多少呢,又是分别在哪些方面产生的耗时呢?

2分析

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

在本文中,消耗资源的分析主要集中在网络上,当然,资源也包括内存、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」分析整个连接的建立过程,如下:

图片

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

其中建立连接的过程具体如下:

  • 第 1 步:建立 TCP 连接,通过三次握手实现。

  • 第 2 步:服务器发送给客户端「握手信息」,客户端响应该握手消息。

  • 第 3 步:客户端「发送认证包」,用于用户验证,验证成功后,服务器返回 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();

图片

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

  • 第 1 步:此时处于 MySQL 通信协议阶段,客户端发送关闭连接请求,而且不用等待服务端的响应。

  • 第 2 步: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 的预编译

  • 负载均衡

  • ……

3总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/58444.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标检测:YOLOv11(Ultralytics)环境配置,适合0基础纯小白,超详细

目录 1.前言 2. 查看电脑状况 3. 安装所需软件 3.1 Anaconda3安装 3.2 Pycharm安装 4. 安装环境 4.1 安装cuda及cudnn 4.1.1 下载及安装cuda 4.1.2 cudnn安装 4.2 创建虚拟环境 4.3 安装GPU版本 4.3.1 安装pytorch(GPU版) 4.3.2 安装ultral…

PostgreSQL 约束

PostgreSQL 约束 介绍 PostgreSQL 是一种功能强大的开源对象关系数据库系统,它提供了多种约束来确保数据的完整性和一致性。约束是数据库规则,用于限制表中数据的类型和操作。在 PostgreSQL 中,约束可以分为几种类型,包括主键约…

telnet远程登陆服务能否用来传输文件(附安装xinetd教程)

通过 telnet 登录到远程服务器之后,你无法直接使用 telnet 发送文件。telnet 协议本身是一个文本协议,主要用于远程登录,不支持文件传输功能。要发送文件,你需要使用其他工具,如 scp 或 sftp。 使用 scp 发送文件 sc…

链表(数据结构)

一. 单链表 1.1 概念与结构 再上一篇中我们讲到顺序表,但是顺序表也是有很多的问题,像申请的空间过多过少或者增容该才能不浪费空间,今天我们就来认识一个新的知识,叫做链表,链表也是线性表的一种,链表是…

(done) 什么 RPC 协议? remote procedure call 远程调用协议

来源:https://www.bilibili.com/video/BV1Qv4y127B4/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 可以理解为,调用远程服务器上的一个方法/函数/服务的方式,同时隐藏网络细节 一个 python3 …

Docker本地安装Minio对象存储

Docker本地安装Minio对象存储 1. 什么是 MinIO? MinIO 是一个开源的对象存储服务器。这意味着它允许你在互联网上存储大量数据,比如文件、图片、视频等,而不需要依赖传统的文件系统。MinIO 的特点在于它非常灵活、易于使用,同时…

数据结构算法学习方法经验总结

DSA:Data Structures, Algorithms, and Problem-Solving Techniques 三大核心支柱 一次学习一个主题,按照如下顺序学习 如何开始学习新的主题 学习资源 https://www.youtube.com/playlist?listPLDN4rrl48XKpZkf03iYFl-O29szjTrs_O (Algorithms) https://ww…

CSRF 攻击 与 SameSite 属性

1. CSRF 攻击介绍 当用户登录银行网站A(例如 bank.com)时,其浏览器会存储认证信息。恶意网站B(例如 attacker.com)可能会包含一个自动提交的请求,模拟用户在银行网站A上的操作,如转账。如果用户…

GSCoolink基石 GSV6127E HDMI2.0/Type-C/DP1.4 转MIPI 可替代CH7515和CS5511

GSCoolink基石 GSV6127E HDMI2.0/Type-C/DP1.4 转MIPI 可替代CH7515和CS5511,适用于PC一体机。 Gscoolink GSV6127E是一款高性能、低功耗的Type-C/DisplayPort 1.4到MIPI CSI-2/LVDS/TTL转换器。使用双端口MIPI接口,可以使用MIPI接口传输真正的4K60 444…

【Linux】Zookeeper 部署

Zookeeper 搭建方式 单机模式:Zookeeper只运行在一台服务器上,适合测试环境伪集群模式:就是在一台物理机上运行多个Zookeeper 实例;集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算…

Java程序设计:spring boot(13)——全局异常与事务控制

1 Spring Boot 事务支持 在使⽤ Jdbc 作为数据库访问技术时,Spring Boot框架定义了基于jdbc的PlatformTransaction Manager 接⼝的实现 DataSourceTransactionManager,并在 Spring Boot 应⽤ 启动时⾃动进⾏配置。如果使⽤ jpa 的话 Spring Boot 同样提供…

00 硬件、嵌入式硬件知识-目录篇

写一下想说的话: 博主本双非、研究生顶2; 做了一两年的fpga,看到师兄师姐的offer情况,结合一下想去的城市,以及个人兴趣 自身情况等等,遂转纯硬件、嵌入式硬件。 本专栏旨在记录博主备战秋招不到一年的时间…

vue2和vue3在html中引用组件component方式不一样

我的vue版本是&#xff1a;20.17.0 一、在HTML中&#xff0c;引用组件格式区别。 vue2引用组件可以是file.vue格式&#xff0c;需要导入&#xff1a;<script src"https://unpkg.com/http-vue-loader"></script>才可以识别vue格式。 vue3引用组件格式是…

Python字典到JSON字符串的转换

在Python中&#xff0c;字典是一种非常常见的数据结构。它可以轻松地转换为JSON字符串&#xff0c;从而实现了将Python对象序列化为JSON格式的目的。本文将详细介绍如何将Python字典转换为JSON字符串。 1. Python字典的基本概念 在Python中&#xff0c;字典是一种无序的键值对…

量子容错计算

基本思想 容错量子计算的基本想法是&#xff0c;在合理编码后的量子态上直接量子计算&#xff0c;以至于不完全需要解码操作。假设有一个简单的量子电路&#xff0c;但不幸的是噪声影响着这个电路的每一个元件&#xff0c;包括量子态的制备、量子逻辑门、对输出的测量&#x…

Redis 哨兵 总结

前言 相关系列 《Redis & 目录》《Redis & 哨兵 & 源码》《Redis & 哨兵 & 总结》《Redis & 哨兵 & 问题》 参考文献 《Redis的主从复制和哨兵机制详解》《Redis中的哨兵&#xff08;Sentinel&#xff09;》《【Redis实现系列】Sentinel自动故…

怎样取消默认逐份打印

如果你遇到打印任务不完成&#xff0c;无法打印下一张的情况&#xff0c;可以尝试下面步骤解决问题&#xff1a; 取消勾选 逐份打印 1、检查打印机状态&#xff1a; 确保打印机与电脑处于联机状态&#xff0c;指示灯应常亮&#xff1b; 2、取消“逐份打印”&#xff1a; 打…

音视频如何轻松转换?来看看这四款工具:

在这个数据普及的时代&#xff0c;视频图片文字等形式的记录&#xff0c;变成了我们习以为常&#xff0c;而传统的文字往往具有搞得信息密度和更强的传播力&#xff1b;我是经常需要将视频内容转换成文&#xff0c;深有体会当下时代将视频内容转化为文字的需求越来越旺盛了&…

highcharts的datalabels标签格式化

Highcharts的数据标签格式化 代码如下 plotOptions: {series: {dataLabels: {enabled: true,format: {y:.2f} mm}} },y就是当前数据点的值&#xff0c;.2f代表2位小数&#xff0c;效果如下图

卡尔曼滤波器-Kalmen Filter-1

卡尔曼滤波器是一种最优递归数据处理算法&#xff0c;它更像是一种观测器&#xff0c;而不是一般意义上的滤波器。卡曼滤波器的应用非常广泛&#xff0c;尤其是在导航当中。它的广泛应用是因为我们生活的世界中存在着大量的不确定性&#xff0c;当我们去描述一个系统的时候&…