颜海东:数据库重启后,为防止应用因为连接池的源不可用的重连配置

    前段时间应用在晚上突然会出现应用不可用的情况,只有经过长时间(大约10分钟)或者应用重启后,访问才能再次正常。查看日志,其中报大量的数据 库连接异常。如下:

        Caused by: com.ibatis.common.jdbc.exception.NestedSQLException:
        --- The error occurred in sqlmaps/price.xml.
        --- The error occurred while applying a parameter map.
        --- Check the dayprice.QUERY-PRICE-BY-THEME-ID-InlineParameterMap.
        --- Check the parameter mapping for the 'themeId' property.
        --- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed.
                at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:185)
                at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForList(GeneralStatement.java:123)
                at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:615)
                at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForList(SqlMapExecutorDelegate.java:589)
                at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForList(SqlMapSessionImpl.java:118)
                at org.springframework.orm.ibatis.SqlMapClientTemplate$3.doInSqlMapClient(SqlMapClientTemplate.java:298)
                at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:209)
                ... 50 more
        Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after statement closed.

    怀疑是数据库连接有问题,因此联系了DBA,DBA查看日志后发现当时数据库进行了一次主库和备份 库之接的切换。为什么要做这个切换呢?这是由于数据库那边有一个HA机制。所 谓HA机制就是数据库的高可用性保障机制,目前价格行情中通过一个心跳机制,每隔一段时间会由备份库去ping主库,如果无法ping通,则会进行一次主 库和备份库之间的切换。
    一开始,认为这是由于数据库重启,导致了不能访问数据库从而导致了应用不可用。但是数据库重启时间只有20秒左右,应该无法导致这么长时间的不可用。然后 在本地机器上安装了mysql数据库进行了测试发现,应用在数据库重启,正常可用之后仍然无法正常 访问。后发现这是由于在数据库重启之后,在连接池中已经在使用的连接均会失效,如果后续的访问不幸取到这些连接的话,则仍然无法正常访问数 据库。
    那么如何使应用在数据库连接失效之后,能够将这些连接马上失效,并取到可用的连接呢?其实很简单,只需要在数据库连接池配置中加一个配置项即可。目前看了 一下各个应用,有三种不同的实现方式:

    1、针对proxool连接池,因此只需要如数据库连接url中加入红圈内的autoReconnect=true即可:


    2、针对DBCP连接池,有两种操作方式:

    2.1)、加一个配置项check-valid-connection-sql,这个配置项的作用是在 sql执行之前执行一条在这个配置项中配置的sql:SELECT @@SQL_PING,根据返回信息来判断这个连接是否可用,如果不可用则将之废弃,然后创建一个新的连接供这个数据库请求使用。


    2.2)、其中的作法也是加了一个配置项,就是exception-sorter-class-name,这个配置项的 作用是捕获数据库请求中所返回的异常,如果是可以判定为该连接失效的异常,则将这个连接废弃。(这个配置项的内容mysql和oracle都有各自的异常 捕获类)



  DBCP中的两种不同的配置方式,各有长处吧,用check-valid-connection-sql可以在连接失效时 重新取得连接来尽量保证此次数据库请求正常,而缺点是每次执行sql都要额外执行一次验证sql;而exception-sorter-class- name虽然不用每次额外执行一条sql,但是在取到失效连接那次访问依然不能使用。

 

    既然DBA那边对数据库配置了HA机制,而且据 DBA说HA机制会偶有“抽风”的现象,因此就会偶 尔的出现这样的切换情况,因此各个应用最好检查下各自的应用中有没有在DBCP中配置相关内容,保证数据库重启后的重连。

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值