【问题标题】:Used jdbc connections seem to be leaking and I cannot figure out why使用的 jdbc 连接似乎正在泄漏,我不知道为什么
【发布时间】:2017-02-18 14:08:26
【问题描述】:

我多年来一直在与这个问题作斗争,但我终其一生都无法弄清楚问题所在。让我为我们正在使用的堆栈做好准备:

  • 基于 Web 的 Java 8 应用程序
  • GWT
  • 休眠 4.3.11
  • MySQL
  • MongoDB
  • 春天
  • Tomcat 8(例如,包括 Tomcat 连接池而不是 C3PO)
  • 休眠搜索/Lucene
  • 兵马俑和 EhCache

问题是每隔几天(有时每隔一天,有时每隔 10 天一次,它会有所不同)在凌晨,我们的应用程序“锁定”。澄清一下,它不会崩溃,您只是无法登录或为此做任何事情。所有后台任务 - 一切 - 只是停止。如果我们在此状态下尝试登录,我们可以在日志文件中看到它正在将我们验证为有效用户,但从未发送任何响应,因此应用程序只是“旋转”。

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

我们使用 JavaMelody 进行监控,我们每次看到的是,在凌晨 1 点到 6 点的窗口中,从不同时间开始,使用的 jdbc 连接数刚刚开始飙升(根据所附图像)。一旦开始,锁定发生只是时间问题,解决它的唯一方法是反弹 Tomcat 从而重新启动应用程序。

据我所知,内存、CPU 等在发生锁定时都很好,唯一看起来有问题的是使用的 jdbc 连接数量不断增加。

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

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

有谁知道是什么导致了这种奇怪的行为?我已经研究了我能想到的一切,但无济于事。

【问题讨论】:

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

标签: java hibernate tomcat jdbc java-melody


【解决方案1】:

经过一段时间的反复试验,我和我的团队设法解决了这个问题。事实证明,JDBC 连接的峰值不是锁定的原因,而是锁定的结果。阿帕奇兵马俑是罪魁祸首。它似乎只是变得没有反应。这可能是资源分配问题,但我不这么认为,因为这发生在使用率低且可用资源充足的服务器上。

幸运的是,我们实际上不再需要 Terracotta,所以我将其移除。正如我在问题中所说,我们每隔几天就会收到这些锁定 - 至少每周一次,每周一次。自从删除它以来,我们已经有 4 个月没有这样的锁定并且还在继续。因此,如果其他人遇到同样的问题并且您正在使用 Terracotta,请尝试放弃它,事情可能会好起来,就像他们在我的情况下所做的那样。

【讨论】:

    【解决方案2】:

    如coladict所说,需要查看javamelody监控报告中的“Opened jdbc connections”页面,在服务器“锁定”之前。

    抱歉,如果您需要在凌晨 2 点或 3 点执行此操作,但也许您可以在晚上自动运行 wget 命令。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多