• HikariPool-1


    线下Tomcat出现故障,查看日志报错:

    HikariPool-1 - Connection is not available, request timed out after 30000ms

    最后调查的问题是:

    某个Service中有个方法使用 httpclient 调用了一个外部接口,而当时这个外部接口服务出现故障,导致httpclient调用卡死了,一直没有响应,因为在Service方法中,也就是在数据库事务中,httpclient调用卡死导致 数据库连接一直无法释放,卡死的httpclient调用不断的增大,数据库连接不断的被占用并且无法释放,最终达到了最大值:

    <!-- 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count) -->
    <property name="maximumPoolSize" value="15" />

    其他功能需要访问数据库时,就报错:HikariPool-1 - Connection is not available, request timed out after 30000ms

    这里问题的关键在于 不能在事务中调用外部接口,不能在事务中有耗时的操作等存在。这样会导致事务变成大事务,长时间占用数据库连接、有可能还导致事务长时间持有相关锁从而导致死锁。

    最佳的解决办法,自然是把 httpclient 外部调用移到事务外面。实时证明,移到事务外面就恢复正常了。

    另外,httpclient 调用应该加上超时现在,比如超过2秒没有返回,就断开:

     URL url = new URL(urlAddress);
     URLConnection conn = url.openConnection();
     conn.setConnectTimeout(2000); 	// 2秒没有连上,则超时
     conn.setReadTimeout(2000); 	// 2秒没有响应,则超时
    

    这样也可以缓解问题。但是最好的方法还是把外部调用移到事务外面!

    这里有个原理需要弄清楚:

    service方法里面就是一个 httpclient 调用,没有查询数据库,为什么还是 会占用数据库连接呢????

    原因是 数据库事务肯定是需要基于数据库连接的!就行我们在mysql客户端里面执行:begin transaction 命令一样,先得连上mysql 。没有连上mysql,无法开启事务。

    这也是为什么在 service方法里面没有查询mysql,但是还是会占用一个数据库连接的原因所在。

      

  • 相关阅读:
    unitTest单元测试框架
    Day06_页面发布与课程管理
    Day05_RabbitMQ研究
    Day04_页面静态化
    Day04_freemarker
    Day03_CMS页面管理开发
    Java概述练习题
    01_语言概述
    00_编程入门
    德道经
  • 原文地址:https://www.cnblogs.com/digdeep/p/14113550.html
Copyright © 2020-2023  润新知