Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用过的jdbc连接似乎正在泄漏,我无法找出原因_Java_Hibernate_Tomcat_Jdbc_Java Melody - Fatal编程技术网

Java 使用过的jdbc连接似乎正在泄漏,我无法找出原因

Java 使用过的jdbc连接似乎正在泄漏,我无法找出原因,java,hibernate,tomcat,jdbc,java-melody,Java,Hibernate,Tomcat,Jdbc,Java Melody,我已经为这个问题奋斗了很多年,我一辈子都搞不清楚问题出在哪里。让我为我们正在使用的堆栈设置舞台: 基于Web的Java8应用程序 GWT 冬眠4.3.11 MySQL 蒙哥达 弹簧 Tomcat 8(例如,包括Tomcat连接池而不是C3PO) Hibernate搜索/Lucene 兵马俑 问题是,每两天(有时是第二天,有时是每10天一次,情况有所不同)清晨,我们的应用程序就会“锁定”。澄清一下,它不会崩溃,你只是不能登录或做任何事情。所有后台任务-所有任务-暂停。如果我们尝试在处于这种状态

我已经为这个问题奋斗了很多年,我一辈子都搞不清楚问题出在哪里。让我为我们正在使用的堆栈设置舞台:

  • 基于Web的Java8应用程序
  • GWT
  • 冬眠4.3.11
  • MySQL
  • 蒙哥达
  • 弹簧
  • Tomcat 8(例如,包括Tomcat连接池而不是C3PO)
  • Hibernate搜索/Lucene
  • 兵马俑
问题是,每两天(有时是第二天,有时是每10天一次,情况有所不同)清晨,我们的应用程序就会“锁定”。澄清一下,它不会崩溃,你只是不能登录或做任何事情。所有后台任务-所有任务-暂停。如果我们尝试在处于这种状态时登录,我们可以在日志文件中看到它正在将我们验证为有效用户,但没有发送响应,因此应用程序只是“旋转”

到目前为止,我们发现的唯一与这些“锁定”发生时间相关的模式是,它发生在我们早上安排的任务或SAP导入正在运行时。但运行的流程并不总是相同的,有时在SAP导入过程中发生锁定,有时在内部计划任务执行过程中发生锁定。所有这些东西的共同点是,它们在工作时间之外(凌晨1点到6点之间)运行,并且它们是相当密集的流程

我们正在使用JavaMelody进行监控,我们每次看到的是,在这个凌晨1-6点的窗口中,从不同的时间开始,使用的jdbc连接数开始激增(如所附的图片所示)。一旦启动,锁定发生只是时间问题,解决它的唯一方法是跳出Tomcat,从而重新启动应用程序

至于我可以告诉你的,内存、CPU等在发生锁定时都很好。唯一看起来有问题的是使用的jdbc连接数量不断增加

我已经多次检查了事务管理的代码,以确保正确关闭事务(事务管理代码非常过时:在try块中显式地开始并提交,在catch块中回滚,在finally块中关闭实体管理器)。对我来说这一切似乎都是正确的,所以我真的,真的很困惑。除此之外,我最近还明确地将Hibernate连接释放模式正确配置为after_事务,但问题仍然存在

另一件奇怪的事情是,我们为不同的客户机运行同一应用程序的多个实例,而这个问题只在一个客户机上经常发生。他们是我们需要处理的数据最多的客户,尽管所有客户都运行这些计划任务,但这个大客户机是唯一一个使用SAP导入的客户机。这就是为什么我最初认为SAP导入是问题所在,但它在今天凌晨1点刚过就锁定了,而那是导入开始运行之前的几个小时。在这种情况下,它在执行内部计划任务时被锁定

有人知道是什么导致了这种奇怪的行为吗?我已经调查了我能想到的一切,但没有结果


正如coladict所说,在服务器“锁定”之前,您需要查看javamelody监控报告中的“打开的jdbc连接”页面


很抱歉,如果您需要在凌晨2小时或3小时执行此操作,但也许您可以在夜间自动运行wget命令。

经过一段时间的反复尝试,我的团队和我成功解决了此问题。结果表明,JDBC连接中的峰值不是锁定的原因,而是锁定的结果。阿帕奇兵马俑就是罪魁祸首。它似乎变得毫无反应了。这可能是一个资源分配问题,但我不这么认为,因为这种情况也发生在使用率低的服务器上,而且它们有足够的可用资源


幸运的是,我们实际上不再需要兵马俑了,所以我把它移走了。正如我在问题中所说的,我们每几天都会被关一次——至少每周一次,每周一次。自从移除它以来,我们已经有4个月没有这样的锁定了。因此,如果其他任何人遇到同样的问题,而您正在使用Terracotta,尝试放弃它,事情可能会好起来,就像他们在我的案例中所做的那样。

您说交易正在关闭,但您是否正在关闭实体经理?您还需要关闭它们,以便将连接释放回池。@coladict我认为这不是真的,因为正如我所提到的,我将连接释放模式设置为after transaction,因此它应该在提交/回滚时释放它们(据我从文档中了解)。无论如何,这是一个没有实际意义的问题,因为我在问题中确实说过,我在finally块中关闭实体管理器。好的,在监控页面的“系统信息”部分有“打开的jdbc连接”链接,可以帮助您查找任何泄漏。如果有任何打开的连接,您将获得创建连接的堆栈跟踪,其峰值可能在Hibernate中的某个位置,但您只需向下移动,直到到达您的类为止。@coladict我看不到该信息的历史记录。当应用程序被锁定时,我无法访问/监控,一旦我跳转了它,“实时”数据就消失了,我只能访问图表上显示的历史数据。至少就我所知,除非你知道在我跳转app/Tomcat之后我可以获取你所指数据的方法。尝试使用jconsole或visualvm或任何其他命令工具(如jmap或jstack)获取线程转储。然后使用ThreadStackAnalyzer分析线程转储(您也可以使用文本编辑器进行分析),并查看谁持有连接。