HikariCP

HikariCP

说明:部分有借鉴,侵权请告知,立删。

数据库连接池,springboot 2.x后默认使用

快。
快速配置:
#数据库连接
spring.datasource.url=*serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=123123
spring.datasource.password=123123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# Hikari连接池的设置
spring.datasource.type=com.zaxxer.hikari.hIkari.HikariDatasource
spring.datasource.hikari.minimumIdle=10
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.pool-name=MyHikariCP
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
参数说明:

autoCommit: 此属性控制从池返回的连接的默认自动提交行为。 它是一个布尔值。 默认值:true

connectionTimeout: 此属性控制客户端(即您)等待池中连接的最大毫秒数。 如果在没有连接可用的情况下超过此时间,则将抛出 SQLException。 最低可接受的连接超时为 250 毫秒。 默认值:30000(30秒)

idleTimeout: 此属性控制允许连接在池中空闲的最长时间。 此设置仅在 minimumIdle 定义为小于maximumPoolSize 时适用。 一旦池达到 minimumIdle 连接,空闲连接将不会退出。 连接是否空闲退出的最大变化为 +30 秒,平均变化为 +15 秒。 在此超时之前,连接永远不会被空闲。 值为 0 表示永远不会从池中删除空闲连接。 允许的最小值为 10000 毫秒(10秒)。 默认值:600000(10分钟)

maxLifetime: 此属性控制池中连接的最长生命周期。 使用中的连接永远不会退役,只有当它关闭时才会被删除。 在逐个连接的基础上,应用轻微的负衰减以避免池中的大量灭绝。 我们强烈建议设置此值,它应比任何数据库或基础结构强加的连接时间限制短几秒。 值 0 表示没有最大生命周期(无限生命周期),当然主题是 idleTimeout 设置。 默认值:1800000(30分钟)

connectionTestQuery: 如果您的驱动程序支持JDBC4,我们强烈建议您不要设置此属性。 这适用于不支持 JDBC4 Connection.isValid()API 的“遗留”驱动程序。 这是在从池中给出连接之前执行的查询,以验证与数据库的连接是否仍然存在。 再次尝试运行没有此属性的池,如果您的驱动程序不符合JDBC4,HikariCP将记录错误以通知您。 默认值:无

minimumIdle: 此属性控制 HikariCP 尝试在池中维护的最小空闲连接数。 如果空闲连接低于此值并且池中的总连接数小于 maximumPoolSize,则 HikariCP 将尽最大努力快速有效地添加其他连接。 但是,为了获得最高性能和对峰值需求的响应,我们建议不要设置此值,而是允许 HikariCP 充当固定大小的连接池。 默认值:与 maximumPoolSize 相同

maximumPoolSize: 此属性控制允许池到达的最大大小,包括空闲和正在使用的连接。 基本上,此值将确定数据库后端的最大实际连接数。 对此的合理值最好由您的执行环境决定。 当池达到此大小,并且没有可用的空闲连接时,对 getConnection() 的调用将在超时前阻塞最多 connectionTimeout 毫秒。 请阅读有关游泳池尺寸的信息。 默认值:10

metricRegistry: 此属性仅可通过编程配置或 IoC 容器获得。 此属性允许您指定池使用的 Codahale / Dropwizard MetricRegistry 的实例来记录各种度量标准。 有关详细信息,请参阅度量维基页面。 默认值:无

healthCheckRegistry: 此属性仅可通过编程配置或IoC容器获得。 此属性允许您指定池使用的 Codahale / Dropwizard HealthCheckRegistry 的实例来报告当前的健康信息。 有关详细信息,请参阅运行状况检查维基页面。 默认值:无

poolName: 此属性表示连接池的用户定义名称,主要显示在日志记录和 JMX 管理控制台中,以标识池和池配置。 默认值:自动生成

线程池大小的设置:

Less Is More

众所周知,一个CPU核心的计算机可以同时执行数十或数百个线程,其实这只是操作系统的一个把戏-time-slicing(时间切片)。实际上,该单核只能一次执行一个线程,然后操作系统切换上下文,并且该内核为另一个线程执行代码,依此类推。这是一个基本的计算法则,给定一个CPU资源,按顺序执行A和B 总是比通过时间片“同时” 执行A和B要快。一旦线程数量超过了CPU核心的数量,添加更多的线程就会变慢,而不是更快。
某用户做过测试(见参考资料),得到结论**1个线程写10个记录比10个线程各写1个记录快。**使用jvisualvm监控程序运行时,也可以看出来thread等待切换非常多。设计多线程是为了尽可能利用CPU空闲等待时间(等IO,等交互…),它的代价就是要增加部分CPU时间来实现线程切换。假如CPU空闲等待时间已经比线程切换更短,(线程越多,切换消耗越大)那么线程切换会非常影响性能,成为系统瓶颈。

其实还有一些因素共同作用,数据库的主要瓶颈是CPU,磁盘,网络(内存还不算最主要的)。

公式:connections =((core_count * 2)+ effective_spindle_count)

effective_spindle_count is the number of disks in a RAID.就是磁盘列阵中的硬盘数,hard disk.某PostgreSQL项目做过测试,一个硬盘的小型4核i7服务器连接池大小设置为: 9 = ((4 * 2) + 1)。这样的连接池大小居然可以轻松处理3000个前端用户在6000 TPS下运行简单查询。

我们公司线上机器标准是2核,有需求可以申请4核、8核,16核一般不开。虚拟机一般都是线程,宿主机一般是2个逻辑CPU。虚拟机默认就一块硬盘,物理机有十几块。

公理:You want a small pool, saturated with threads waiting for connections.

在公式的配置上,如果加大压力,TPS会下降,RT会上升,你可以适当根据情况进行调整加大。这时考虑整体系统性能,考虑线程执行需要的等待时间,设计合理的线程数目。但是,不要过度配置你的数据库

Pool-locking 池锁

增大连接池大小可以缓解池锁问题,但是扩大池之前是可以先检查一下应用层面能够调优,不要直接调整连接池大小
避免池锁是有一个公式的:

pool size = Tn x (Cm - 1) + 1

T n是线程的最大数量,C m是单个线程持有的同时连接的最大数量。
例如,设想三个线程(T n = 3),每个线程需要四个连接来执行某个任务(C m = 4)。确保永不死锁的池大小是: 3 x(4 - 1)+ 1 = 10。
另一个例子,你最多有8个线程(T n = 8),每个线程需要三个连接来执行一些任务(C m = 3)。确保死锁永远不可能的池大小是: 8×(3-1)+ 1 = 17

  • 这不一定是最佳池大小,但是是避免死锁所需的最低限度。
  • 在某些环境中,使用JTA(Java事务管理器)可以显着减少从同一个Connection返回getConnection()到当前事务中已经存储Connection的线程所需的连接数。
具体问题具体分析

混合了长时间运行事务和非常短的事务的系统通常是最难调整任何连接池的系统。在这些情况下,创建两个池实例可以很好地工作(例如,一个用于长时间运行的作业,另一个用于“实时”查询)。
如果长期运行的外部系统,例如只允许一定数量的作业同时运行的作业执行队列,这是作业队列大小就是连接池非常合适的大小。

最后,我要说的是:

连接池大家是综合每个应用系统的业务逻辑特性,加上应用硬件配置,加上应用部署数量,再加上db硬件配置和最大允许连接数测试出来的。很难有一个简单公式进行计算。连接数及超时时间设置不正确经常会带来较大的性能问题,并影响整个服务能力的稳定性。具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。压测很重要。

数据连接超时反馈

  • HikariCP:等待5秒钟后,如果连接还是没有恢复,则抛出一个SQLExceptions 异常;后续的getConnection()也是一样处理;
  • C3P0:完全没有反应,没有提示,也不会在“CheckoutTimeout”配置的时长超时后有任何通知给调用者;然后等待2分钟后终于醒来了,返回一个error;
  • Tomcat:返回一个connection,然后……调用者如果利用这个无效的connection执行SQL语句……结果可想而知;大约55秒之后终于醒来了,这时候的getConnection()终于可以返回一个error,但没有等待参数配置的5秒钟,而是立即返回error;
  • BoneCP:跟Tomcat的处理方法一样;也是大约55秒之后才醒来,有了正常的反应,并且终于会等待5秒钟之后返回error了;

连接池指标连接:https://mp.weixin.qq.com/s?__biz=MzUzNTY4NTYxMA==&mid=2247483699&idx=1&sn=5efd1f9d872688eba0029c71b3668662&chksm=fa80f1b6cdf778a0bbd12ce5e97507d697058d7bc070082a8ca828c9910c1379ead43c7b9a05&scene=21#wechat_redirect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shichangle01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值