有关Hikaricp连接池配置的解读

        HiKari源于日语“光”的意思,HiKariCP顾名思义就是 和光速一样快,HiKariCP是数据库连接池的一个后起之秀,号称性能最好,稳定性也不错,完美地PK掉其他连接池。这里提供一篇文章介绍主流Java数据库连接池比较及前瞻,文中重点介绍了当前主流开源数据库连接池(比如C3P0、DBCP、Tomcat Jdbc Pool、Druid和Hikaricp)的性能分析和功能比较,有一定的参考价值。

       回到本文正题,近期在计费生产系统上遇到一个很头疼的问题——Hikaricp连接池获取不到连接数而连接不到数据库,导致请求失败。每10笔交易会出现2笔,具体异常如下:

Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 932347ms.

at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:555) ~[HikariCP-2.4.7.jar:?]

at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:188) ~[HikariCP-2.4.7.jar:?]

at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:147) ~[HikariCP-2.4.7.jar:?]

at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:99) ~[HikariCP-2.4.7.jar:?]

at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) ~[spring-jdbc-4.3.5.RELEASE.jar:4.3.5.RELEASE]

at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) ~[spring-jdbc-4.3.5.RELEASE.jar:4.3.5.RELEASE]

at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:82) ~[mybatis-spring-1.2.3.jar:1.2.3]

at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:68) ~[mybatis-spring-1.2.3.jar:1.2.3]

at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:315) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:75) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:61) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:303) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:154) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:102) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:82) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120) ~[mybatis-3.3.0.jar:3.3.0]

at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113) ~[mybatis-3.3.0.jar:3.3.0]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_79]

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_79]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_79]

at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_79]

at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:386) ~[mybatis-spring-1.2.3.jar:1.2.3]

... 26 more

问题分析:

1、异常抛出时间每次都是在15分30秒左右,但该系统的并行环境并没有此异常,生产环境的差异只是数据库部署在不同的主机上;

2、访问数据库命令的网络耗时正常,数据库端收到连接请求,且该时段数据库连接数并没有耗尽;

3、数据库管理员在异常时间段查询得知,不存在慢sql语句,不存在不合理设置索引导致此异常。

继续分析,只能从Hikaricp的配置着手:以下是出异常的数据源配置 

自此附上hikarecp各个配置的中文解释:hikariCP连接池配置

<bean id="dataSourcePubdba" class="com.zaxxer.hikari.HikariDataSource">

     <property name="driverClassName" value="${datasource.driver}">

     <property name="jdbcUrl" value="${datasource.jdbcUrl}">

     <property name="username" value="${datasource.user}">

     <property name="password" value="${datasource.pass.encrypt}">

     <property name="connectionTimeout" value="30000" />

    <property name="idleTimeout" value="60000" />

     <property name="maxLifetime" value="1800000" />

     <property name="maximumPoolSize" value="65" />

</bean>

后四个重要参数的解释:

    1)connectionTimeout:等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒 

    2)idleTimeout:此属性控制允许连接在池中闲置的最长时间,此设置仅适用于minimumIdle设置为小于maximumPoolSize的情况 默认:600000(10minutes)

   2)maxLifetime:一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒

3)maximumPoolSize:连接池中允许的最大连接数(包括空闲和正在使用的连接)。缺省值:10;

综合以上分析:connectionTimeout采用默认值30s,应该不会有太大问题。maximumPoolSize根据业务量的设置,不会有太大问题。maxLifetime如果过长,且idleTimeout没有时间限制时,会导致连接数很大,空闲连接一直得不到释放,严重挤占资源,容易引起连接数不够的问题。特别是maxLifetime如果大于数据库超时时长,就会抛出数据库连接异常,这也是本次生产问题所在:maxLifetime设置成30分钟,超过了数据库连接时长15分钟,connectionTimeout为30秒,所以每次异常都是在15分30秒抛出,数据库端已经收到Hikaricp连接请求,但是因网络问题等因素,到达超时时长而没有获取到连接。idleTimeout只有在minimumIdle设置为小于maximumPoolSize的情况下才生效,而我没有设置最小空闲连接数minimumIdle的值,minimumIdle默认是等于maximumPoolSize,此时idleTimeout不受限,空闲连接一直没有得到回收,出于系统优化以及并发稳定性考虑,应该增加此配置。

优化后的配置:

<bean id="dataSourceTxndba" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close" >//对象销毁前调用了close函数,这是必须的,否则对象离开后,数据库资源还可用

       <property name="driverClassName" value="${datasource.driver}"></property>

       <property name="jdbcUrl" value="${datasource.jdbcUrl2}"></property>

       <property name="username" value="${datasource.user2}"></property>

       <property name="password" value="${datasource.pass2.encrypt}"></property>

       <property name="connectionTimeout" value="30000" />

       <property name="idleTimeout" value="60000" />

       <property name="maxLifetime" value="600000" />

       <property name="minimumIdle" value="10" />

       <property name="maximumPoolSize" value="65" />

       <property name="poolName" value="TxnDatabasePool" />

       <property name="leakDetectionThreshold" value="5000"/>

</bean>

相比较之前的配置,优化点如下:

 1、增加数据连接关闭方法,当从dataSource获取的连接使用完成后,调用close方法,以避免数据源对象任然可用,造成连接泄露

 2、增加最小空闲连接数minimumIdle,根据业务场景,设置为10,小于maximumPoolSize值

3、连接空闲时间idleTimeout生效,根据业务请求重发频率为40多秒,值可设为1分钟,减少空闲连接占用,尽快释放数据库连接

4、连接生命周期maxLifetime值设为10分钟,低于数据库超时时长,尽快释放数据库无效连接

5、增加连接池的用户定义名称

6、开启连接监测泄露leakDetectionThreshold方法,此属性控制在记录消息之前连接可能离开池的时间量,表明可能的连接泄漏。值代表连接被占用的泄露时间最低可接受值为5秒,不过此值的设定需要根据场景多次调试,如果真实泄露时间小幅度超过5秒,会引起warning,但不一定会导出数据不能入库,因为该方法只是检查,只有到达idleTimeout ,才会强制执行关闭连接。

运行结果:

 使用该配置,目前系统暂未发生数据库连接异常现象,后续还会继续跟踪,以期获得最优配置。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容