HikariCP
HiKariCP是数据库连接池的一个后起之秀,号称性能最好,可以完美地PK掉其他连接池。
为何要使用HiKariCP?这要先从BoneCP说起:
什么?不是有C3P0/DBCP这些成熟的数据库连接池吗?一直用的好好的,为什么又搞出一个BoneCP来?因为,传说中BoneCP在快速这个特点上做到了极致,官方数据是C3P0等的25倍左右。不相信?其实我也不怎么信。可是,有图有真相啊(图片来自BoneCP官网:http://jolbox.com/benchmarks.html):
![6c5ade02f5b7d9adf8c9a7882d87426c.png](https://img-blog.csdnimg.cn/img_convert/6c5ade02f5b7d9adf8c9a7882d87426c.png)
而且,网上对于BoneCP是好评如潮啊,推荐的文章一搜一大堆。
然而,上Maven Repository网站(http://mvnrepository.com/artifact/com.jolbox/bonecp)查找有没有最新版本的时候,你会发现最新的是2013年10月份的(这么久没新版本出来了?)。于是,再去BoneCP的Githut(https://github.com/wwadge/bonecp)上看看最近有没有提交代码。却发现,BoneCP的作者对于这个项目貌似已经心灰意冷,说是要让步给HikariCP了(有图有真相):
![c6934798ee50a0c9b20db27d1ae3a9a9.png](https://img-blog.csdnimg.cn/img_convert/c6934798ee50a0c9b20db27d1ae3a9a9.png)
……什么?又来一个CP?……什么是Hikari?
Hikari来自日文,是“光”(阳光的光,不是光秃秃的光)的意思。作者估计是为了借助这个词来暗示这个CP速度飞快。不知作者是不是日本人,不过日本也有很多优秀的码农,听说比特币据说日本人搞出来的。。。
这个产品的口号是“快速、简单、可靠”。实际情况跟这个口号真的匹配吗?又是有图有真相(Benchmarks又来了):
![4e039d6b9103875eae9aff9fe6b000a8.png](https://img-blog.csdnimg.cn/img_convert/4e039d6b9103875eae9aff9fe6b000a8.png)
英文:
constrained 不舒服的,被强迫的,拘泥的;
这个图,也间接地、再一次地证明了boneCP比c3p0强大很多,当然,跟“光”比起来,又弱了不少啊。
那么,这么好的CP是怎么做到的呢?官网详细地说明了HikariCP所做的一些优化,总结如下:
- 字节码精简:优化代码,直到编译后的字节码最少,这样,CPU缓存可以加载更多的程序代码;
- 优化代理和拦截器:减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一;
- 自定义数组类型(FastStatementList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描;
- 自定义集合类型(ConcurrentBag):提高并发读写的效率;
- 其他针对BoneCP缺陷的优化,比如对于耗时超过一个CPU时间片的方法调用的研究(但没说具体怎么优化)。
很多优化的对比都是针对BoneCP的……哈哈。
(参考文章:https://github.com/brettwooldridge/HikariCP/wiki/Down-the-Rabbit-Hole)
几个连接池的代码量对比(代码量越少,一般意味着执行效率越高、发生bug的可能性越低):
![51605fcfa1a5ab19cd5d46b8db216859.png](https://img-blog.csdnimg.cn/img_convert/51605fcfa1a5ab19cd5d46b8db216859.png)
可是,“黄婆卖瓜,自催自擂”这个俗语日本人也是懂得,于是,用户的好评如潮也是有图有真相:
![19af682638f62ebdeea7cdef7eb67292.png](https://img-blog.csdnimg.cn/img_convert/19af682638f62ebdeea7cdef7eb67292.png)
还有第三方关于速度的测试:
![aaad77f18e14b1e76762f2ee0a4143bc.png](https://img-blog.csdnimg.cn/img_convert/aaad77f18e14b1e76762f2ee0a4143bc.png)
也许你会说,速度高,如果不稳定也是硬伤啊。于是,关于稳定性的图也来了:
![446ed509ce04bd03178351f512ddf895.png](https://img-blog.csdnimg.cn/img_convert/446ed509ce04bd03178351f512ddf895.png)
另外,关于可靠性方面,也是有实验和数据支持的。对于数据库连接中断的情况,通过测试getConnection(),各种CP的不相同处理方法如下:
(所有CP都配置了跟connectionTimeout类似的参数为5秒钟)
HikariCP:等待5秒钟后,如果连接还是没有恢复,则抛出一个SQLExceptions 异常;后续的getConnection()也是一样处理;
C3P0:完全没有反应,没有提示,也不会在“CheckoutTimeout”配置的时长超时后有任何通知给调用者;然后等待2分钟后终于醒来了,返回一个error;
Tomcat:返回一个connection,然后……调用者如果利用这个无效的connection执行SQL语句……结果可想而知;大约55秒之后终于醒来了,这时候的getConnection()终于可以返回一个error,但没有等待参数配置的5秒钟,而是立即返回error;
BoneCP:跟Tomcat的处理方法一样;也是大约55秒之后才醒来,有了正常的反应,并且终于会等待5秒钟之后返回error了;
可见,HikariCP的处理方式是最合理的。根据这个测试结果,对于各个CP处理数据库中断的情况,评分如下:
![a46180c6b84eceecb1f1aee6797c15c4.png](https://img-blog.csdnimg.cn/img_convert/a46180c6b84eceecb1f1aee6797c15c4.png)
HikariCP是数据库连接池,而且是号称史上最快的,而且目前来看确实是这样的,SpringBoot2.0也已经采用HikariCP作为默认连接池配置.
Java识堂,一个高原创,高收藏,有干货的微信公众号,一起成长,一起进步,欢迎关注