connectionTimeout:控制客户端在获取池中 Connection 的等待时间,如果没有连接可用的情况下超过该时间,则抛出 SQLException 异常,比如说 getConnection时连接数已经大于 maximumPoolSize 并且一直没有空闲的连接 。默认 30 s。
idleTimeout:控制 Connection 闲置在池中的最大时间。当 minimumIdle 值大于 maximumPoolSize 小时才生效,而且只有当池中 Connection 数量大于 minimumIdle 时才根据该时间进行 Connection 剔除。默认为 600000 s(10 分钟)。
maxLifetime:控制池中 Connection 的最大生命周期。处于使用中的 Connection 不会因为自身生命超出该时间而被剔除,只有等到被归还关闭后才会被剔除。HikariCP 作者强烈建议用户设置该值,并且它应该比任何数据库服务的连接事件限制短几秒。默认为 1800000 s(30分钟)。
connectionTestQuery:控制数据库连接池借出 Connection 前对其进行检查,如果使用的 Driver 是 JDBC4 则不建议设置该属性。不配做会使用 ping 命令进行检查,其性能大致为 select 1 的1倍左右。默认为无。
minimumIdle:控制池中维护的空闲 Connection 的最小数量。如果空闲连接数大小该数值,并且总连接数小于 maximumPoolSize,则 HikariCP 将尽力快速添加新的 Connection。默认等于 maximumPoolSize。
maximumPoolSize:控制数据库连接池 Connection 的最大数量,包括空闲和正在使用的。
对于 minimumIdle 和 maximumPoolSize 对数据库连接数量的影响如下图所示,当 minimumIdle 小于 maximumPoolSize 时,连接数量会在该区间内变化,空闲时间超过 idleTimeout 的连接会被剔除,直到数量变为 minimumIdle 位置。
但是 HikariCP 的作者建议不设置 minimumIdle,或将其设置为maximumPoolSize 相同数值(默认也是如此),将 HikariCP 充当一个固定大小的连接池使用,这样可以最大限度提高性能和对突发流量的相应能力。
HikariCP 对于这些配置的默认值都进行最优配置,使用时往往不需要调整。但是使用场景千变万化,有些情况下还是需要根据自己的情况进行调整,后续文章会对较为重要的几个属性的影响和调整技巧做详细的说明。
为什么这么快官网详细地说明了 HikariCP 所做的一些优化,总结如下:
字节码精简 :优化代码,直到编译后的字节码最少,这样,CPU 缓存可以加载更多的程序代码;
优化代理和拦截器:减少代码,例如 HikariCP 的 Statement proxy 只有100行代码,只有 BoneCP 的十分之一;
自定义的 FastList 代替 ArrayList:避免每次 get 调用都要进行 range check,避免调用 remove 时的从头到尾的扫描;
自定义集合类型 ConcurrentBag,提高并发读写的效率;
其他针对 BoneCP 缺陷的优化,比如对于耗时超过一个 CPU 时间片的方法调用的研究(但没说具体怎么优化)
HikariCP 具体的优化细节可以阅读作者写的《Down the Rabbit Hole》一文(地址链接在文末),Rabbit Hole 是指兔子洞,寓意是复杂奇艺且未知的境地,来自爱丽丝漫游奇境记中爱丽丝掉入兔子洞。
下面我们就简单说明一下几项优化。
使用 FastList 替代 ArrayListHikariCP 通过分析 Connection 使用 Statement 的场景,提出了使用 FastList 代替 ArrayList 的优化方案。
FastList 是一个 List 接口的精简实现,只实现了接口中必要的几个方法。它主要做了如下几点优化:
ArrayList 每次调用 get 方法时都会进行 rangeCheck 检查索引是否越界,其实只要保证索引合法那么 rangeCheck 就成为不必要的计算开销。因此,FastList 不会进行该检查。
ArrayList 的 remove(Object) 方法是从头开始遍历数组,而 FastList 是从数组的尾部开始遍历,在 HikariCP 使用的场景下更为高效。