Java MySQL/Hibernate-如何调试不断下降的MySQL池连接?
几个月来,我的web应用程序运行平稳,但在过去一两周里,它不断断开与MySQL服务器的连接。我不是DBA,也不知道如何调试它 以下是我所知道的:Java MySQL/Hibernate-如何调试不断下降的MySQL池连接?,java,mysql,database,hibernate,orm,Java,Mysql,Database,Hibernate,Orm,几个月来,我的web应用程序运行平稳,但在过去一两周里,它不断断开与MySQL服务器的连接。我不是DBA,也不知道如何调试它 以下是我所知道的: 连接似乎每隔几个小时就会中断一次。有时在白天,但总是在晚上 我的实验室有一个MySQL服务器,为多个应用程序托管数据库 目前,我们有46个到MySQL服务器的连接 据我所知,没有其他应用程序遇到此问题 我的应用程序与另一个应用程序使用相同的堆栈、配置甚至代码连接到DB。另一个应用程序每天支持大约200个用户,自2013年以来一直运行平稳 两个应用程序都
<!-- TomcatJDBCConnectionProvider class is common to both applications -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.TomcatJDBCConnectionProvider</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.pool_size">5</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.tomcatJdbcPool.validationQuery">SELECT 1</property>
<property name="hibernate.tomcatJdbcPool.testOnBorrow">true</property>
<property name="hibernate.enable_lazy_load_no_trans">true</property>
它似乎在堆栈跟踪上迭代,找到带有文本“放弃的连接清理线程”
的跟踪,然后手动停止它。似乎这可能与我的问题有关
编辑2015年9月21日:
这个周末我的申请被驳回了。这是昨天的错误日志中的堆栈跟踪(我相信它已经停止了):
以下是我的MySQL连接变量:
mysql> SHOW VARIABLES LIKE '%connect%';
+-----------------------------------------------+-----------------+
| Variable_name | Value |
+-----------------------------------------------+-----------------+
| character_set_connection | utf8 |
| collation_connection | utf8_general_ci |
| connect_timeout | 5 |
| default_master_connection | |
| extra_max_connections | 1 |
| init_connect | |
| max_connect_errors | 100 |
| max_connections | 100 |
| max_user_connections | 0 |
| performance_schema_session_connect_attrs_size | 512 |
+-----------------------------------------------+-----------------+
mysql> SHOW VARIABLES LIKE '%timeout%';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 5 |
| deadlock_timeout_long | 50000000 |
| deadlock_timeout_short | 10000 |
| delayed_insert_timeout | 300 |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| thread_pool_idle_timeout | 60 |
| wait_timeout | 28800 |
+-----------------------------+----------+
编辑2015年9月22日:
严重的Tomcat错误会导致问题吗?我看到一个与数据库无关的错误,关于解析日期:
22-Sep-2015 10:09:53.481 SEVERE [http-apr-8080-exec-26] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [edu.mssm.pharm.maayanlab.Harmonizome.page.DatasetPage] in context with path [/Harmonizome] threw exception [javax.servlet.ServletException: javax.servlet.jsp.JspException: In <parseDate>, a parse locale can not be established] with root cause
javax.servlet.jsp.JspException: In <parseDate>, a parse locale can not be established
at org.apache.taglibs.standard.tag.common.fmt.ParseDateSupport.doEndTag(ParseDateSupport.java:147)
正在附加堆内存使用率的JConsole输出:
用于线程使用的JConsole输出;它大约从24-25岁开始,当我开始使用这个网站时,它跳到了34岁。即使在关闭浏览器窗口后,它仍然存在:
编辑2015年9月23日:
在问题开始之前,我改变了一件事,那就是如何处理Hibernate事务。以前,我禁用了enable\u lazy\u load\u no\u trans
(这是默认设置)。以前,我使用的是“”模式。人们似乎不喜欢视图中的开放会话模式,所以我启用了启用\u lazy\u load\u no\u trans
。因此,我有如下代码:
List<MyObjects> myObjects = null;
try {
HibernateUtil.beginTransaction();
myObjects = // fetch my objects from the DB
HibernateUtil.commitTransaction();
} catch (HibernateException he) {
HibernateUtil.rollbackTransaction();
} finally {
HibernateUtil.close();
}
// render myObjects in JSP/JSTL
// this JSP may lazily load related objects
List myObjects=null;
试一试{
HibernateUtil.beginTransaction();
myObjects=//从数据库获取我的对象
HibernateUtil.commitTransaction();
}捕获(冬眠异常he){
HibernateUtil.rollbackTransaction();
}最后{
HibernateUtil.close();
}
//在JSP/JSTL中呈现MyObject
//此JSP可能会延迟加载相关对象
回想起来,这似乎。。。有问题的我不知道Hibernate什么时候“放开”对象。Hibernate错误有点抽象,有时通过堆栈跟踪发现错误可能很棘手。我认为这可能是您的应用程序的问题,可能在某些情况下您没有正确关闭Hibernate连接,或者您的应用程序可能存在内存泄漏 您是否尝试过使用JDK中的
jconsole
监视应用程序
您可以在Java参数中的Tomcat配置控制台上设置它(我假设您使用的是Tomcat),以启用jconsole
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8086
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
然后连接到远程进程,例如
localhost:8086
并在执行使应用程序停止的操作时观察线程
编辑
如果您没有使用Tomcat,并且您正在Windows环境中运行应用程序,您可以使用例如监视线程并监视应用程序。从您提供的堆栈跟踪中,我可以得出一个结论:您只是在运行连接 这可能是由于长时间运行的事务造成的,可能是由于查询速度慢或应用程序事务边界不正确 我建议您开始使用,它支持Tomcat DBCP,并更好地了解连接和事务使用。 FlexyPool提供了许多您可能感兴趣的功能,如连接获取时间和租赁时间
为了安全起见,还需要检查MySQL驱动程序的版本,看看您是否在一个过时的库上运行。您的连接池似乎无法在超时时间内返回到Hibernate的免费连接。这是因为应用程序具有很长的事务或事务死锁。您可以尝试以下选项来修复该错误
5
max_connections
,并继续测试
org.apache.commons
commons-dbcp2
2.1
还有其他替代解决方案,例如将等待超时更改为更高的值。但这对应用程序性能没有好处,对于事务死锁也没有任何意义。最后,为了提高数据库的性能,您应该记住在进一步的开发中关注事务管理和数据库结构。内存问题?在部署Mysql和应用程序的机器上部署了其他应用程序吗?我对这个连接池实现没有经验,但我会开始调试QueryTimeoutInterceptor:@Gaurav,其他几个小应用程序正在同一台机器上运行。我们有一个集群
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=8086
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
localhost:8086