为什么我们的 Tomcat Java 应用程序突然打开数百个到我们数据库的连接?

为什么我们的 Tomcat Java 应用程序突然打开数百个到我们数据库的连接?

我们有一个在 Elastic Beanstalk 上运行的 Tomcat 应用程序,我们的 MySQL 数据库托管在 AWS RDS(2 或 3 个 t3.medium 实例)上。自从我们从 MySQL 5 升级到 MySQL 8(当前为 8.0.23)以来,我们一直遇到一个问题,大约每周发生一次。大多数时候数据库都很好,但是突然之间,连接数猛增(有时甚至在 1 分钟内超过 307 个连接的限制,这也是我们无法理解的。它怎么能超越这个限制?)这导致 Elastic Beanstalk 实例降级。有时整个数据库在这些连接达到峰值后崩溃。

在使用 VisualVM 监控应用程序的 JVM 时,我注意到,在连接高峰期间,Tomcat 突然创建了数十个工作线程。我猜想这些线程中的每一个都会与数据库建立新的连接。虽然我们可以限制这些线程的数量(毕竟服务器首先无法处理这么多线程),但我们想了解导致这种情况的原因。为什么 Tomcat 会创建这么多线程和与数据库的连接?这是数据库问题的原因还是结果?我们应该在哪里寻找问题的根源?

我搜索了很多次,试图找到遇到过类似问题的人,以便弄清楚这个问题。我们还尝试分析最昂贵的查询和其他数据库性能洞察,但似乎没有明确的模式。

答案1

我们应该去哪里寻找问题的根源?

  • 在 MySQL 中启用慢速日志并(在峰值之后)调查当时正在运行的查询。如果慢速日志没有显示太多内容,请long_query_time在下一次峰值之前降低。
  • (不知道Tomcat有没有日志。)
  • 它每天或每周的同一时间发生吗?
  • 亚马逊何时进行备份?
  • 如果发生这种情况时您在线,请尝试SHOW PROCESSLIST;。保持连接;当您看到峰值时,连接可能会很困难。
  • MySQL“变量”max_connections控制 307。增加它可能会推迟峰值的出现,但会使情况变得更糟。(我不认为这是一个“解决方案”。)
  • Tomcat 可以 [可能] 阻止过多的连接,而不会造成太大的损害;限制 Tomcat 可能比更改 307 更好。当 MySQL 有“大量繁忙连接”时,它会为每个连接提供平等的资源访问权限;这会导致速度变慢全部连 接。

相关内容