Springboot 2.0选择HikariCP作为默认数据库连接池的五大理由

转载自公众号:工匠小猪猪的技术世界

摘要: 本文非原创,是笔者搜集了一些HikariCP相关的资料整理给大家的介绍,主要讲解了为什么sb2选择了HikariCP以及HikariCP为什么这么快。

Springboot2默认数据库连接池选择了HikariCP为何选择HikariCP理由一、代码量理由二、口碑理由三、速度理由四、稳定性理由五、可靠性HikariCP为什么这么快优化并精简字节码更好的并发集合类实现使用FastList替代ArrayListHikariCP与Druid相比哪个更好?Springboot2快速上手参考资料

Spring Boot 2默认数据库连接池选择了HikariCP

默认的数据库连接池由Tomcat换成HikariCP. 如果在一个Tomcat应用中用spring.datasource.type来强制使用Hikari连接池, 则可以去掉这个override.

为何选择HikariCP

HiKariCP是数据库连接池的一个后起之秀,号称性能最好,可以完美地PK掉其他连接池,是一个高性能的JDBC连接池,基于BoneCP做了不少的改进和优化。其作者还有另外一个开源作品——高性能的JSON解析器HikariJSON。

它,超快,快到连Spring Boot 2都宣布支持了。

代码体积更是少的可怜,130kb。

https://github.com/brettwooldridge/HikariJSON

为何要使用HiKariCP?这要先从BoneCP说起:
什么?不是有C3P0/DBCP这些成熟的数据库连接池吗?一直用的好好的,为什么又搞出一个BoneCP来?因为,传说中BoneCP在快速这个特点上做到了极致,官方数据是C3P0等的25倍左右。不相信?其实我也不怎么信。可是,有图有真相啊(图片来自BoneCP官网:http://jolbox.com/benchmarks.html):

从上述结果可以看出HikariCP的性能远高于c3p0、tomcat等连接池,以致后来BoneCP作者都放弃了维护,在Github项目主页推荐大家使用HikariCP。另外,Spring Boot将在2.0版本中把HikariCP作为其默认的JDBC连接池。

PS:需要指出的是,上图中的数据是HikariCP作者对各个连接池调用DataSource.getConnection()、Connection.close()、Connection.prepareStatement()、Statement.execute()、Statement.close()方法的性能测试结果。

而且,网上对于BoneCP是好评如潮啊,推荐的文章一搜一大堆。

然而,上Maven Repository网站(http://mvnrepository.com/artifact/com.jolbox/bonecp)查找有没有最新版本的时候,你会发现最新的是2013年10月份的(这么久没新版本出来了?)。于是,再去BoneCP的Githut(https://github.com/wwadge/bonecp)上看看最近有没有提交代码。却发现,BoneCP的作者对于这个项目貌似已经心灰意冷,说是要让步给HikariCP了(有图有真相):

……什么?又来一个CP?……什么是Hikari?
Hikari来自日文,是“光”(阳光的光,不是光秃秃的光)的意思。作者估计是为了借助这个词来暗示这个CP速度飞快。不知作者是不是日本人,不过日本也有很多优秀的码农,听说比特币据说日本人搞出来的。。。

这个产品的口号是“快速、简单、可靠”。实际情况跟这个口号真的匹配吗?又是有图有真相(Benchmarks又来了):

这个图,也间接地、再一次地证明了boneCP比c3p0强大很多,当然,跟“光”比起来,又弱了不少啊。

那么,这么好的是怎么做到的呢?官网详细地说明了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的可能性越低):

理由二、口碑

可是,“黄婆卖瓜,自催自擂”这个俗语日本人也是懂得,于是,用户的好评如潮也是有图有真相:

理由三、速度

还有第三方关于速度的测试:

理由四、稳定性

也许你会说,速度高,如果不稳定也是硬伤啊。于是,关于稳定性的图也来了:

理由五、可靠性

另外,关于可靠性方面,也是有实验和数据支持的。对于数据库连接中断的情况,通过测试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处理数据库中断的情况,评分如下:

参考文章:https://github.com/brettwooldridge/HikariCP/wiki/Bad-Behavior:-Handling-Database-Down

HikariCP为什么这么快

JDBC连接池的实现并不复杂,主要是对JDBC中几个核心对象Connection、Statement、PreparedStatement、CallableStatement以及ResultSet的封装与动态代理。接下来从几个方面来看看HikariCP为什么这么快:

优化并精简字节码

HikariCP利用了一个第三方的Java字节码修改类库Javassist来生成委托实现动态代理。动态代理的实现在ProxyFactory类,源码如下:

发现这些代理方法中只有一行直接抛异常的代码,注释写着“Body is replaced (injected) by JavassistProxyFactory”,其实方法body中的代码是在编译时调用JavassistProxyFactory才生成的,主要代码见下图:

之所以使用Javassist生成动态代理,是因为其速度更快,相比于JDK Proxy生成的字节码更少,精简了很多不必要的字节码。

ConcurrentBag:更好的并发集合类实现

ConcurrentBag的实现借鉴于C#中的同名类,是一个专门为连接池设计的lock-less集合,实现了比LinkedBlockingQueue、LinkedTransferQueue更好的并发性能。ConcurrentBag内部同时使用了ThreadLocal和CopyOnWriteArrayList来存储元素,其中CopyOnWriteArrayList是线程共享的。ConcurrentBag采用了queue-stealing的机制获取元素:首先尝试从ThreadLocal中获取属于当前线程的元素来避免锁竞争,如果没有可用元素则再次从共享的CopyOnWriteArrayList中获取。此外,ThreadLocal和CopyOnWriteArrayList在ConcurrentBag中都是成员变量,线程间不共享,避免了伪共享(false sharing)的发生。

使用FastList替代ArrayList

FastList是一个List接口的精简实现,只实现了接口中必要的几个方法。JDK ArrayList每次调用get()方法时都会进行rangeCheck检查索引是否越界,FastList的实现中去除了这一检查,只要保证索引合法那么rangeCheck就成为了不必要的计算开销(当然开销极小)。此外,HikariCP使用List来保存打开的Statement,当Statement关闭或Connection关闭时需要将对应的Statement从List中移除。通常情况下,同一个Connection创建了多个Statement时,后打开的Statement会先关闭。ArrayList的remove(Object)方法是从头开始遍历数组,而FastList是从数组的尾部开始遍历,因此更为高效。

HikariCP与Druid相比哪个更好?

有些用户给了druid这样的评论:

不评论,一个追求性能,一个偏向监控,直接看之前有人给HikariCP提的关于跟Druid对比分析的issue吧。HikariCP作者对Druid做了测试并给出了测试结果数据,Druid作者温少也对此作了评论。Issue链接:

https://github.com/brettwooldridge/HikariCP/issues/232

笔者个人的观点是,hikariCP可以提供监控功能的,比如metrics,可以参见笔者的这篇文章 【追光者系列】HikariCP连接池监控指标实战。
另外,监控方面,skywalking、pinpoint、mycat这些agent也是可以做到的,以后service mesh普及了更加可以监控了,比如sharding-jdbc也可以做监控,datamesh,sidecar也可以做监控的。

Springboot2快速上手

说得这么好,用起来会不会很麻烦啊,会不会有很多参数要配置才能有这样的效果啊?答案是:不会。

springboot 2.0 默认连接池就是Hikari了,所以引用parents后不用专门加依赖

配置一下就好

# jdbc_config   datasource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/datebook?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
spring.datasource.username=root
spring.datasource.password=root
# Hikari will use the above plus the following to setup connection pooling
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1

直接启动即可 如图

参考资料

https://blog.csdn.net/clementad/article/details/46928621


money.jpg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/477343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

剑指Offer - 面试题13. 机器人的运动范围(BFS/DFS)

文章目录1. 题目2. 解题2.1 BFS2.2 DFS1. 题目 地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入…

聊聊“润(run)”

文 | One day知乎大家好,我是one day。前不久,我和知乎大V陈然老师在广州的台风天上午,线上聊了一杯咖啡时间的天,老师帮忙解答了一些疑虑,share了一些自己的想法。主要是围绕 美国湾区互联网工作氛围、大厂&创业公…

Spring Boot使用@Async实现异步调用:使用Future以及定义超时

之前连续写了几篇关于使用Async实现异步调用的内容,也得到不少童鞋的反馈,其中问题比较多的就是关于返回Future的使用方法以及对异步执行的超时控制,所以这篇就来一起讲讲这两个问题的处理。 如果您对于Async注解的使用还不了解的话&#xf…

《程序员面试金典》解题目录(更新完毕)

题目来源于LeetCode上的《程序员面试金典》,这里做一个目录方便大家查找。另外有本人的LeetCode解题目录、《剑指Offer》解题目录、LintCode代码能力测试CAT 解题目录可点击链接查看。updated on 2020.4.17 不懂的概念可以参考《数据结构与算法之美》学习汇总 已解…

我竟在一篇AI顶会论文里见到了小猪佩奇...

声明:本文原创首发于公众号夕小瑶的卖萌屋。作者:智商掉了一地--->【我是传送门】,内含海量CV/NLP/ML入门资料、必刷综述、前沿论文解读、交流社群、offer神器、学习神器等在介绍接下来的内容前,我们先来看一则笑话&#xff1a…

程序员面试金典 - 面试题 01.01. 判定字符是否唯一(位运算,牛)

1. 题目 实现一个算法&#xff0c;确定一个字符串 s 的所有字符是否全都不同。 示例 1&#xff1a; 输入: s "leetcode" 输出: false 示例 2&#xff1a; 输入: s "abc" 输出: true限制&#xff1a; 0 < len(s) < 100 如果你不使用额外的数据结构…

Spring Boot快速开发利器:Spring Boot CLI

Spring Boot CLI&#xff08;Command Line Interface&#xff09;是一个命令行工具&#xff0c;您可以用它来快速构建Spring原型应用。通过Spring Boot CLI&#xff0c;我们可以通过编写Groovy脚本来快速的构建出Spring Boot应用&#xff0c;并通过命令行的方式将其运行起来。下…

微软发现了一个超简单的NLP上分技巧,还发了ACL2022 ??

文 | QvQ编 | Sheryc_王苏今天给大家介绍一篇来自工业界巨头微软的工作&#xff0c;这篇论文真是把资本家的嘴脸暴露的一览无余&#xff1a;用最低的成本&#xff0c;创造最高的收益&#xff08;狗头.jpg&#xff09;文章从头到尾就阐述了一个结论&#xff1a;通过在输入文本中…

程序员面试金典 - 面试题 01.05. 一次编辑(编辑距离,DP)

1. 题目 字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串&#xff0c;编写一个函数判定它们是否只需要一次(或者零次)编辑。 示例 1: 输入: first "pale" second "ple" 输出: True示例 2: 输入: first "pa…

Spring Boot使用@Async实现异步调用:ThreadPoolTaskScheduler线程池的优雅关闭

上周发了一篇关于Spring Boot中使用Async来实现异步任务和线程池控制的文章&#xff1a;《Spring Boot使用Async实现异步调用&#xff1a;自定义线程池》。由于最近身边也发现了不少异步任务没有正确处理而导致的不少问题&#xff0c;所以在本文就接前面内容&#xff0c;继续说…

MIT毕业生亲述:在Deepmind打工是一种什么样的体验?

文 | Akhil Raju源 | 机器之心在这里&#xff0c;既有头脑风暴&#xff0c;也有生活气息。本月初&#xff0c;时任苹果机器学习总监的 Ian Goodfellow 宣布在加入公司三年后辞职&#xff0c;没过几天&#xff0c;就有消息曝出大神去向定了&#xff0c;他将重返谷歌加入 DeepMin…

LeetCode 72. 编辑距离(DP)

1. 题目 给定两个单词 word1 和 word2&#xff0c;计算出将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符删除一个字符替换一个字符 示例 1: 输入: word1 "horse", word2 "ros" 输出: 3 解…

毕业后到底去学术界还是工业界?杜克大学陈怡然教授亲述5条“小秘籍”

文 | 卖萌酱大家好&#xff0c;我是卖萌酱。今天和大家聊一个非常受关心的话题&#xff1a;毕业到底是去学术界还是工业&#xff1f;刚好最近看到杜克大学陈怡然教授在微博上对此有亲身感悟&#xff1a;陈怡然教授认为回学校而不去公司有以下几个理由&#xff1a;1. 我不喜欢随…

程序员面试金典 - 面试题 17.11. 单词距离(multimap平衡二叉搜索树)

1. 题目 有个内含单词的超大文本文件&#xff0c;给定任意两个单词&#xff0c;找出在这个文件中这两个单词的最短距离(相隔单词数)。 如果寻找过程在这个文件中会重复多次&#xff0c;而每次寻找的单词不同&#xff0c;你能对此优化吗? 示例&#xff1a; 输入&#xff1a;w…

腾讯薪酬改革来了!晋升≠加薪?员工到底为何工作?

文 | 天于刀刀这届打工人真的是太太太难了&#xff01;朝九晚九地写PPT&#xff0c;熬KPI&#xff0c;疫情它来了&#xff1b;终于习惯了隔离核酸&#xff0c;走出EMO&#xff0c;隔壁工位的同学被毕业了&#xff1b;最终凭着玄学幸运留组&#xff0c;还没来得及准备庆祝一下六…

Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题

LocalDate、LocalTime、LocalDateTime是Java 8开始提供的时间日期API&#xff0c;主要用来优化Java 8以前对于时间日期的处理操作。然而&#xff0c;我们在使用Spring Boot或使用Spring Cloud Feign的时候&#xff0c;往往会发现使用请求参数或返回结果中有LocalDate、LocalTim…

LeetCode 1054. 距离相等的条形码(优先队列)

1. 题目 在一个仓库里&#xff0c;有一排条形码&#xff0c;其中第 i 个条形码为 barcodes[i]。 请你重新排列这些条形码&#xff0c;使其中两个相邻的条形码 不能 相等。 你可以返回任何满足该要求的答案&#xff0c;此题保证存在答案。 示例 1&#xff1a; 输入&#xff1a…

Meta AI团队大换血!组织拆散,高管离职,LeCun进军元宇宙??

编 | 桃子 时光源 | 新智元【导读】全力助攻元宇宙&#xff0c;Meta人工智能部门要重组了&#xff01;今天&#xff0c;Yann LeCun发文表示&#xff0c;Meta的人工智能实验室FAIR将整合到Reality Labs中。另外&#xff0c;任职4年的人工智能高管Jerome Pesenti也宣布了将要离职…

【译】Spring Boot 2.0 官方迁移指南

前提 希望本文档将帮助您把应用程序迁移到 Spring Boot 2.0。 在你开始之前 首先&#xff0c;Spring Boot 2.0 需要 Java 8 或更高版本。不再支持 Java 6 和 7 了。 在 Spring Boot 2.0 中&#xff0c;许多配置属性被重新命名/删除&#xff0c;开发人员需要更新application…

剑指Offer - 面试题22. 链表中倒数第k个节点(快慢指针)

1. 题目 输入一个链表&#xff0c;输出该链表中倒数第k个节点。为了符合大多数人的习惯&#xff0c;本题从1开始计数&#xff0c;即链表的尾节点是倒数第1个节点。例如&#xff0c;一个链表有6个节点&#xff0c;从头节点开始&#xff0c;它们的值依次是1、2、3、4、5、6。这个…