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[…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
