SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP
SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP
本文是SpringBoot第35讲,主要介绍数据库连接池,以及SpringBoot集成默认的HikariCP的实践。
文章目录
- SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP
- 1、知识准备
- 1.1、什么是数据库连接池?
- 1.2、数据库连接池基本原理?
- 1.3、有哪些常见的数据库连接池?
- 2、简单示例 (商品中心采用的方案)
- 3、进一步理解
- 3.1、SpringBoot2默认连接池HikariCP是如何起作用的?
- 3.2、更多HikariCP配置参数?
- 3.3、为什么HikariCP会成为默认连接池?
- 3.4、更多常见的使用问题
- 4、源码示例
1、知识准备
需要理解数据库连接池的基本原理,Java DataSource规范,常见的连接池等。部分内容整理自百度百科
1.1、什么是数据库连接池?
什么是连接池,它要解决什么样的问题呢?
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接,来避免因为没有释放数据库连接 而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
1.2、数据库连接池基本原理?
连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
数据库连接池的最小连接数和最大连接数的设置要考虑到下列几个因素:
- 最小连接数
是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
- 最大连接数
是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。
- 最小连接数与最大连接数差距
最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求 等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用 或是空闲超时后被释放。
1.3、有哪些常见的数据库连接池?
开源的数据库连接池众多,这里我们需要了解曾经常用的开源数据库连接池及其被淘汰原因,并了解目前最常用的数据库连接池。
- C3P0(被淘汰:历史悠久,过于复杂,性能差)
是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。由于一度是Hibernate内置的数据库连接池而被开发者熟知,但是由于性能和复杂度,官方已经放弃维护。
- DBCP(被淘汰:依赖Commons-Pool,性能差) DBCP(DataBase Connection Pool)属于Apache顶级项目Commons中的核心子项目。但DBCP并不是独立实现连接池功能的,它内部依赖于Commons-Pool项目,连接池最核心的“池”,就是由Commons-Pool组件提供的,因此,DBCP的性能实际上就是Pool的性能。
终于在tomcat 7.0版本中,tomcat重新设计开发出了一套连接池(Tomcat JDBC Pool)并且于13年9月发布了Commons-Pool 2.0。命脉已经更新的DBCP终于在14年2月份发布了DBCP2.0。但是,毕竟由于长时间没有更新突破的DBCP,已经被人放弃了。
- BoneCP(被淘汰:为解决C3P0/DBCP性能而生,后续出现了更高性能的hikariCP,BoneCP也不再更新)
是一个快速、开源的数据库连接池。帮用户管理数据连接,让应用程序能更快速地访问数据库。
BoneCP的出现主要是为了解决C3P0/DBCP连接池性能问题,有一些测试表明其性能提升了25倍。
后来出现了更高性能的hikariCP,BoneCP也不再更新,所以BoneCP目前也很少被使用。
- Druid
Druid功能最为全面,sql拦截等功能,统计数据较为全面,具有良好的扩展性
2、简单示例 (商品中心采用的方案)
主要展示HikariCP的使用配置等。
如下是常用的HikariCP的使用配置(Springboot 默认连接池)
spring:datasource:url: jdbc:mysql://localhost:3306/db_user?useSSL=false&autoReconnect=true&characterEncoding=utf8driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: qwj930828# 指定为HikariDataSourcetype: com.zaxxer.hikari.HikariDataSource# hikari连接池配置hikari:#连接池名pool-name: HikariCP#最小空闲连接数minimum-idle: 5# 空闲连接存活最大时间,默认10分钟idle-timeout: 600000# 连接池最大连接数,默认是10maximum-pool-size: 10# 此属性控制从池返回的连接的默认自动提交行为,默认值:trueauto-commit: true# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认30分钟max-lifetime: 1800000# 数据库连接超时时间,默认30秒connection-timeout: 30000# 连接测试queryconnection-test-query: SELECT 1
3、进一步理解
通过如下几个问题,进一步理解HikariCP。
3.1、SpringBoot2默认连接池HikariCP是如何起作用的?
从SpringBoot自动初始化配置 和 默认的数据源 两个角度理解。
- SpringBoot自动初始化配置
关键代码如下
然后可以找到HikariCP数据源的配置
你可以发现,为了支持动态更新配置(基于MXBean),这里还设计了一层HikariConfigMXBean接口
- 为什么说是默认的数据源呢?
首先,springboot-starter-jdbc中默认加载了Hikari
其次,在配置初始化或者加载时都是第一个被加载的
private static <T extends DataSource> MappedDataSourceProperties<T> lookupPooled(ClassLoader classLoader,Class<T> type) {MappedDataSourceProperties<T> result = null;result = lookup(classLoader, type, result, "com.zaxxer.hikari.HikariDataSource",HikariDataSourceProperties::new);result = lookup(classLoader, type, result, "org.apache.tomcat.jdbc.pool.DataSource",TomcatPoolDataSourceProperties::new);result = lookup(classLoader, type, result, "org.apache.commons.dbcp2.BasicDataSource",MappedDbcp2DataSource::new);result = lookup(classLoader, type, result, "oracle.ucp.jdbc.PoolDataSourceImpl",OraclePoolDataSourceProperties::new, "oracle.jdbc.OracleConnection");return result;
}
3.2、更多HikariCP配置参数?
从代码的角度,你已经可以看到,可以配置如下属性:
private volatile String catalog;private volatile long connectionTimeout;private volatile long validationTimeout;private volatile long idleTimeout;private volatile long leakDetectionThreshold;private volatile long maxLifetime;private volatile int maxPoolSize;private volatile int minIdle;private volatile String username;private volatile String password;// Properties NOT changeable at runtime//private long initializationFailTimeout;private String connectionInitSql;private String connectionTestQuery;private String dataSourceClassName;private String dataSourceJndiName;private String driverClassName;private String exceptionOverrideClassName;private String jdbcUrl;private String poolName;private String schema;private String transactionIsolationName;private boolean isAutoCommit;private boolean isReadOnly;private boolean isIsolateInternalQueries;private boolean isRegisterMbeans;private boolean isAllowPoolSuspension;private DataSource dataSource;private Properties dataSourceProperties;private ThreadFactory threadFactory;private ScheduledExecutorService scheduledExecutor;private MetricsTrackerFactory metricsTrackerFactory;private Object metricRegistry;private Object healthCheckRegistry;private Properties healthCheckProperties;private long keepaliveTime;private volatile boolean sealed;
更具体的可以看官方配置 或者参考这篇博客:深蓝Blog总结翻译的配置
属性 | 描述 | 构造器默认值 | 默认配置validate之后的值 | validate重置 |
---|---|---|---|---|
autoCommit | 自动提交从池中返回的连接 | TRUE | TRUE | – |
connectionTimeout | 等待来自池的连接的最大毫秒数 | SECONDS.toMillis(30) = 30000 | 30000 | 如果小于250毫秒,则被重置回30秒 |
idleTimeout | 连接允许在池中闲置的最长时间 MINUTES.toMillis(10) = 600000 | 600000 | 如果idleTimeout+1秒>maxLifetime 且 maxLifetime>0,则会被重置为0(代表永远不会退出);如果idleTimeout!=0且小于10秒,则会被重置为10秒 | |
maxLifetime | 池中连接最长生命周期 | MINUTES.toMillis(30) = 1800000 | 1800000 | 如果不等于0且小于30秒则会被重置回30分钟 |
connectionTestQuery | 如果您的驱动程序支持JDBC4,我们强烈建议您不要设置此属性 | null | null | – |
minimumIdle | 池中维护的最小空闲连接数 | -1 | 10 | minIdle<0或者minIdle>maxPoolSize,则被重置为maxPoolSize |
maximumPoolSize | 池中最大连接数,包括闲置和使用中的连接 | -1 | 10 | 如果maxPoolSize小于1,则会被重置。当minIdle<=0被重置为DEFAULT_POOL_SIZE则为10;如果minIdle>0则重置为minIdle的值 |
metricRegistry | 该属性允许您指定一个 Codahale / Dropwizard MetricRegistry 的实例,供池使用以记录各种指标 | null | null | – |
healthCheckRegistry | 该属性允许您指定池使用的Codahale / Dropwizard HealthCheckRegistry的实例来报告当前健康信息 | null | null | – |
poolName | 连接池的用户定义名称,主要出现在日志记录和JMX管理控制台中以识别池和池配置 | null | HikariPool-1 | – |
initializationFailTimeout | 如果池无法成功初始化连接,则此属性控制池是否将 fail fast | 1 | 1 | – |
isolateInternalQueries | 是否在其自己的事务中隔离内部池查询,例如连接活动测试 | FALSE | FALSE | – |
allowPoolSuspension | 控制池是否可以通过JMX暂停和恢复 | FALSE | FALSE | – |
readOnly | 从池中获取的连接是否默认处于只读模式 | FALSE | FALSE – | |
registerMbeans | 是否注册JMX管理Bean(MBeans) | FALSE | FALSE – | |
catalog | 为支持 catalog 概念的数据库设置默认 catalog driver | default | null | – |
connectionInitSql | 该属性设置一个SQL语句,在将每个新连接创建后,将其添加到池中之前执行该语句。 | null | null | – |
driverClassName | HikariCP将尝试通过仅基于jdbcUrl的DriverManager解析驱动程序,但对于一些较旧的驱动程序,还必须指定driverClassName | null | null | – |
transactionIsolation | 控制从池返回的连接的默认事务隔离级别 | null | null | – |
validationTimeout | 连接将被测试活动的最大时间量 | SECONDS.toMillis(5) = 5000 | 5000 | 如果小于250毫秒,则会被重置回5秒 |
leakDetectionThreshold | 记录消息之前连接可能离开池的时间量,表示可能的连接泄漏 | 0 | 0 | 如果大于0且不是单元测试,则进一步判断:(leakDetectionThreshold < SECONDS.toMillis(2) or (leakDetectionThreshold > maxLifetime && maxLifetime > 0),会被重置为0 . 即如果要生效则必须>0,而且不能小于2秒,而且当maxLifetime > 0时不能大于maxLifetime |
dataSource | 这个属性允许你直接设置数据源的实例被池包装,而不是让HikariCP通过反射来构造它 | null | null | – |
schema | 该属性为支持模式概念的数据库设置默认模式 driver | default | null | – |
threadFactory | 此属性允许您设置将用于创建池使用的所有线程的 java.util.concurrent.ThreadFactory 的实例。 | null | null | – |
scheduledExecutor | 此属性允许您设置将用于各种内部计划任务的java.util.concurrent.ScheduledExecutorService 实例 | null | null | – |
3.3、为什么HikariCP会成为默认连接池?
官网详细地说明了 HikariCP 所做的一些优化,总结如下:
- 字节码精简 :优化代码,直到编译后的字节码最少,这样,CPU缓存可以加载更多的程序代码;
- 优化代理和拦截器:减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一;
- 自定义数组类型(FastStatementList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描;
- 自定义集合类型(ConcurrentBag):提高并发读写的效率;
- 其它:针对BoneCP缺陷的优化,比如对于耗时超过一个CPU时间片的方法调用的研究等。
更多可以参考:Down the Rabbit Hole
3.4、更多常见的使用问题
请参考 官方WIKI - FAQ
4、源码示例
todo
springBoot默认HikariDataSource配置
相关文章:

SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP
SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP 本文是SpringBoot第35讲,主要介绍数据库连接池,以及SpringBoot集成默认的HikariCP的实践。 文章目录 SpringBoot第35讲:SpringBoot集成连接池 - 默认连接池HikariCP1…...

选择最适合自己的笔记本
选择最适合自己的笔记本电脑 一、了解笔记本品牌一线品牌准一线品牌二线品牌三线品牌 二、笔记本入手渠道笔记本入手渠道 三、根据需求选择机型使用需求1.日常使用2.商务办公、财务3.轻度剪辑、ps4.代码5.创意设计6.游戏 四、笔记本电脑配置如何选1.cpu2.显卡(GPU&a…...
前端安全:探秘安全 HTTP 头的设置
在当今数字化时代,前端安全至关重要。除了应对常见的攻击方式外,通过设置安全 HTTP 头,我们可以加强网站的安全性,减少潜在的威胁。本文将为您详细解释什么是安全 HTTP 头,以及如何通过设置它们来保护您的前端应用。 1…...

python爬虫——爬虫伪装和反“反爬”
前言 爬虫伪装和反“反爬”是在爬虫领域中非常重要的话题。伪装可以让你的爬虫看起来更像普通的浏览器或者应用程序,从而减少被服务器封禁的风险;反“反爬”则是应对服务器加强的反爬虫机制。下面将详细介绍一些常见的伪装和反反爬技巧,并提…...
vue3 使用 element-china-area-data 实现地区选择器
官方地址:https://www.npmjs.com/package/element-china-area-data?activeTabreadme 在线示例:https://plortinus.github.io/element-china-area-data/index.html 实际使用 <el-col :span"12"><el-form-item label"所处城市&…...

STM32自带的DSP库的滤波初体验(一)
最近在弄STM32自带的DSP库里的滤波,记录一下: arm_fir_instance_q15 instance_q15_S; #define NUM_TAPS 16 //滤波系数的个数 #define BLOCK_SIZE 32 q15_t firStateF32[BLOCK_SIZE NUM_TAPS]; q15_t Fir_Coeff[NUM_TAPS] {-79, -136, 312, 6…...
go kratos protobuf 接收动态JSON数据
前言 google.protobuf.Struct 是 Google Protocol Buffers 中的一种特殊类型,用于表示动态的键值对数据。它可以存储任意类型的数据,并提供了方便的方法来访问和操作这些数据。 Struct 类型通常用于在不事先知道数据结构的情况下传递和处理配置、参数或其…...
Python学习笔记第五十四天(Pandas DataFrame)
Python学习笔记第五十四天 Pandas 数据结构 - DataFrame使用列表创建使用 ndarrays 创建使用字典创建返回多行数 后记 Pandas 数据结构 - DataFrame DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符…...

Docker镜像查看下载删除镜像文件的相关命令
1.镜像相关命令 本地查看有哪些镜像文件: docker images镜像的名称就是我们常见的一些软件,镜像相当于把软件和软件所需要的运行环境打包到一个镜像文件里面,将来在通过这个镜像文件创建出对应的容器,容器有了以后这些软件自动的…...
1. VisionOS平台介绍
介绍 VisionOS 可实现与现实世界无缝集成并与其他虚拟内容共存的 3D 多任务体验。这为个人生产力、生活方式和娱乐应用打开了一个充满新可能性的世界,并为开发人员打开了一个全新的市场。然而,它也带来了围绕多任务处理和与身体互动的新挑战。Unity Poly…...
【C#】设置有线网卡IP地址,子网掩码,网关,DNS
方法 public partial class ComputerInfo{/// <summary>/// 设置IP地址,子网掩码,网关,DNS/// </summary>public static List<NetworkAdapterInfo> SetIpAddressSubMaskDnsGeteway(string ipAddress, string subMask, stri…...
LVS-DR集群及NGINX负载均衡
LVS-DR集群 原理: 1. 当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间 2. PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链 3. IPVS是工作在…...

React如何配置env环境变量
React版本: "react": "^18.2.0" 1、在package.json平级目录下创建.env文件 2、在‘.env’文件里配置环境变量 【1】PUBLIC_URL 描述:编译时文件的base-href 官方描述: // We use PUBLIC_URL environment variable …...

VR全景智慧文旅,用科技助力旅游业振兴
引言: 近年来,科技的迅猛发展将我们带入一个全新的数字化时代,而虚拟现实(Virtual Reality,简称VR)技术则以其令人惊叹的全新方式,影响着各个领域。其中,旅游业作为人们探索世界、体…...

系统架构设计专业技能 · 系统安全分析与设计(四)【加解密、数字信封、信息摘要、数字签名、数字书证、网络安全、信息安全】
系列文章目录 系统架构设计专业技能 网络规划与设计(三)【系统架构设计师】 系统架构设计专业技能 系统安全分析与设计(四)【系统架构设计师】 系统架构设计高级技能 软件架构设计(一)【系统架构设计师…...

基于WebSocket的在线文字聊天室
与Ajax不同,WebSocket可以使服务端主动向客户发送响应,本案例就是基于WebSocket的一个在线聊天室,不过功能比较简单,只能满足文字交流。演示如下。 案例学习于b站up主,链接 。这位up主讲的非常清楚,值得去学…...

VS Code中C++程序的调试(Debug)功能
有一个.vscode文件,存放当前工作区相关配置文件的目录。 launch.json {"version": "0.2.0","configurations": [{"name": "gcc.exe - 生成和调试活动文件", // 该调试任务的名字,启动调试时会在待…...
C#四个字节十六进制与单精度浮点数互转
C#四个字节十六进制与单精度浮点数互转可以使用自带的函数,也可以自己写 实例如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace floatDemo {class Program{//首先设置:项目->属性…...
Springloc和aop的基础概念
什么是控制反转和依赖注入? 控制反转(IoC)和依赖注入(DI)是软件开发中常用的编程范式, 它们极大地提高了代码可维护性和可复用性,简化了代码结构。 什么是控制反转(IoC) 控制反转是- - 种编程模式,它将应用程序中的控制权转移到…...
算法练习Day43|● 518. 零钱兑换 II ● 377. 组合总和 Ⅳ
LeetCode:518. 零钱兑换 II 518. 零钱兑换 II - 力扣(LeetCode) 1.思路 求组合数,先遍历物品再遍历背包,dp[]数组累加即可。 2.代码实现 1class Solution {2 public int change(int amount, int[] coins) {34 int[…...

单片机0-10V电压输出电路分享
一、原理图 二、芯片介绍 GP8101是一个PWM信号转模拟信号转换器,相当于一个PWM信号输入,模拟信号输出的DAC。此 芯片可以将占空比为0%到100%的PWM信号线性转换成0-5V或者0-10V的模拟电压,并且输出电压 精度小于1%。GP8101M可以处理高频调制的…...
mysql+keepalived
文章目录 一、master1创建目录写入配置文件启动master1创建 `slave` 用户并授权获取主节点当前 `binary log` 文件名和位置position二、master2创建目录写入配置文件启动master2创建 `slave` 用户并授权获取主节点当前 `binary log` 文件名和位置position三、配置主主复制Maste…...
Kafka 核心架构与消息模型深度解析(二)
案例实战:Kafka 在实际场景中的应用 (一)案例背景与需求介绍 假设我们正在为一个大型电商平台构建数据处理系统。该电商平台拥有庞大的用户群体,每天会产生海量的订单数据、用户行为数据(如浏览、点击、收藏等&#…...

Python打卡第46天
浙大疏锦行 注意力 注意力机制是一种让模型学会「选择性关注重要信息」的特征提取器,就像人类视觉会自动忽略背景,聚焦于图片中的主体(如猫、汽车)。 从数学角度看,注意力机制是对输入特征进行加权求和,…...

企业培训学习考试系统源码 ThinkPHP框架+Uniapp支持多终端适配部署
在数字化转型浪潮下,企业对高效培训与精准考核的需求日益迫切。一套功能完备、多终端适配且易于定制的培训学习考试系统,成为企业提升员工能力、检验培训成果的关键工具。本文给大家分享一款基于 ThinkPHP 框架与 Uniapp 开发的企业培训学习考试系统&…...
微服务常用日志追踪方案:Sleuth + Zipkin + ELK
在微服务架构中,一个用户请求往往需要经过多个服务的协同处理。为了有效追踪请求的完整调用链路,需要一套完整的日志追踪方案。Sleuth Zipkin ELK 组合提供了完整的解决方案 Sleuth:生成和传播追踪IDZipkin:收集、存储和可视化…...
Lua和JS的继承原理
JavaScript 和 Lua 都是动态语言,支持面向对象编程(OOP),但它们的 继承机制 实现方式不一样。下面分别介绍它们的继承实现原理和方式: 🔶 JavaScript 的继承机制 JavaScript 使用的是 基于原型(…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信拓扑与操作 BR/EDR(经典蓝牙)和 BLE
目录 1. BR/EDR(经典蓝牙)网络结构微微网(Piconet)散射网(Scatternet)蓝牙 BR/EDR 拓扑结构示意图 2. BLE(低功耗蓝牙)网络结构广播器与观察者(Broadcaster and Observer…...

Git GitHub Gitee
一、Git 是一个免费、开源的分布式版本控制系统。 版本控制:一种记录文件内容变化,以便将来查阅特定版本修订情况的系统。它最重要的就是可以记录文件修改历史记录,从而让用户可以看历史版本,方便版本切换。 1.和集中式版本控制…...

Vue3 + UniApp 蓝牙连接与数据发送(稳定版)
本教程适用于使用 uni-app Vue3 (script setup) 开发的跨平台 App(支持微信小程序、H5、Android/iOS 等) 🎯 功能目标 ✅ 获取蓝牙权限✅ 扫描周围蓝牙设备✅ 连接指定蓝牙设备✅ 获取服务和特征值✅ 向设备发送数据包(ArrayBu…...