问题描述
- 在系统访问高峰期出现无法获取数据库连接的异常
-
最近遇到一个棘手的问题,请教各位能否查明报出异常的原因:
1:正常情况下系统运行没有问题,但是系统访问高峰情况下会出现,日志如下,这段日志出现一段时间之后,应用就会假死,持续1分钟左右之后恢复。
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException
: javax.resource.ResourceException: IJ000453: Unable to get managed connection for java:jboss/datasources/PnrDS
The error may exist in com/huifu/muser/common/dal/dao/MerUsrMapMapper.xml
The error may involve com.huifu.muser.common.dal.dao.MerUsrMapMapper.queryMerUsrMap
The error occurred while executing a query
Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is java.sql.SQLException: javax.resource.ResourceE
xception: IJ000453: Unable to get managed connection for java:jboss/datasources/PnrDS
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:365)
at com.sun.proxy.$Proxy157.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:195)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:124)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:90)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)
at com.sun.proxy.$Proxy158.queryMerUsrMap(Unknown Source)
at com.huifu.muser.service.core.cash.impl.CashReqServiceImpl.checkMerUsrMap(CashReqServiceImpl.java:267)
at com.huifu.muser.biz.cash.impl.CashReqManager2Impl.cashConfirmReq(CashReqManager2Impl.java:211)
at com.huifu.muser.webapp.controller.cash.CashController.cashConfirm2(CashController.java:200)
at sun.reflect.GeneratedMethodAccessor2127.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)2:我的应用框架是 spring3.0.5+mybatis3.1.1+JBoss7.1+oracle11+jdk1.6
3:负载均衡 netscaler,两台虚拟机,四核,内存8G,jvm启动参数配置如下:
-XX:+UseCompressedOops -XX:+TieredCompilation -Xms4096m -Xmx4096m -Xmn1024m -XX:PermSize=256M -XX:MaxPermSize=512M -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -XX:SurvivorRatio=8 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -Xnoclassgc -XX:+CMSClassUnloadingEnabled
4:我的数据库链接池是配置在jboss的配置文件standalone-ha.xml中,连接池配置为18-300,高峰期能达到300,即应用确实与数据库建立300链接,但是活跃链接在15左右,配置如下
解决方案
Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection;
看下你的jdbc的最大连接数是多少?
解决方案三:
jdbc最大连接数多少?提供片段读取写入的代码,看一下你重用连接的代码。
解决方案四:
查看一下数据库的日志 里面一般有描述当前数据库连接的问题等 看是连接数太多还是数据处理问题
解决方案五:
" 连接池配置为18-300,高峰期能达到300 "
说明高峰期瞬间连接数确实可能超过300,那你分别把配置文件中max-pool-size调大一点,比如到400或500,然后确认Oracle最大进程数够用;再试试就可以了。
https://developer.jboss.org/thread/211940?start=0
解决方案七:
直接原因就是 CannotGetJdbcConnectionException
当数据库连接到了设定最大值时,再想获得连接,就出错了
一方面,要检查是否有连接用完没关闭的情况
如果没问题,那么就要加大最大连接数了
你可以监控一下数据库本身,如果忙得时候很慢,会导致很多连接无法及时完成而无法释放,此时加大连接数只能更糟糕
这时你只能优化数据的软硬件和应用本身了