该问题产生的现象

页面刷新几次后,就卡住,线上就得需要重新部署(还好是测试环境,不是真正生产环境)

过程及原因

  1. 查看日志线程池满了
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60010, active 20, maxActive 20                  at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)                  at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:280)                  ... 64 more  Caused by: com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60010, active 20, maxActive 20                  at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1071)                  at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:898)                  at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4544)
  1. 原因

Mybatis中有一种不用写mapper和mapper.xml也可以和数据库连接的方法:通过使用sqlSession执行拼接好的sql,直接运行,在创建连接时候(继承SqlSessionDaoSupport)获取sqlMapper,使用了getSessionFactory().openSession(),配置中使用druid连接池,导致一个现象就是,用到这个sqlMapper的页面,只要刷新个几次就卡住了,导致每次不得不重启系统,如果是线上就得次次重新部署。

解决过程及办法

  1. 一开始先尝试,增加了druid的回收机制配置(properties配置文件,改为yml同理)
#druid recycle Druid的连接回收机制#超过时间限制是否回收spring.datasource.druid.removeAbandoned = true#超时时间;单位为秒。180秒=3分钟spring.datasource.druid.removeAbandonedTimeout = 180#关闭abanded连接时输出错误日志spring.datasource.druid.logAbandoned = true

通过这种办法,卡住了过一会再刷新就好了(也是概率问题,有的时候也会卡着),但这样也影响使用,未从根本解决问题

  1. 通过线程池总是达到最大值,判断是否是druid未回收之前的连接

经过debug,反复测试:原来是getSessionFactory().openSession()的锅,所以改为了SqlSessionDaoSupport.getSqlSession()这个方法,再通过SqlMapper sqlMapper = new SqlMapper(getSqlSession())获取sqlMapper得以解决问题。