【问题标题】:Application is running out postgres connections after JDK upgradeJDK 升级后应用程序正在用完 postgres 连接
【发布时间】:2022-01-27 13:57:22
【问题描述】:

我将我的 grails 应用程序从 JDK 8 升级到 JDK 11。我们有一些自动化测试,在 JDK8 中运行良好。 但是现在使用 JDK11,我会在一段时间后得到这个异常:

 org.postgresql.util.PSQLException: FATAL: remaining connection slots are reserved for non-replication superuser connections

这两个 JDK 版本中 Postgres 连接池的行为有区别吗?我没有更改升级配置中的任何内容或更改 Postgres.conf 中的任何内容。

【问题讨论】:

  • 您确定没有其他应用程序实际连接到数据库吗?使用“select * from pg_stat_activity”检查它,查看列 client_addr。
  • 是的,我确定。它在我的本地开发者计算机上,只有我的应用程序连接到 postgres。

标签: java postgresql grails


【解决方案1】:

所以最可能的解释是你有资源泄漏。您的应用程序......或您的测试用例(!)......正在泄漏数据库连接。

如果是这种情况,根本原因就在您的代码中。


典型的 JDBC 驱动程序会尝试通过使用 finalize 方法或 Cleaner 或类似的方法来保护自己免受资源泄漏,以在发现无法访问时关闭 Connection 和相关对象。问题是这些机制仅在 GC 检测到对象不再可访问后才会启动。

这就是 Java 版本更改可能发挥作用的地方。 GC 的行为是 Java 版本敏感的,直接因为 GC 实现本身发生变化,或者间接因为默认堆大小、“新空间”和“旧空间”大小默认值、默认使用参数等可能会发生变化。因此,GC 可能会花费更长的时间来查找和关闭已被应用程序删除的 Connection 对象。

如果删除了太多 Connection 对象,并且/或者 GC 没有足够快地找到它们,那么您最终会打开太多连接,并且数据库后端不会再让您打开。

这两个JDK版本中Postgres连接池的行为有区别吗?

连接池依赖 GC 来处理您的应用程序未返回池的池连接......以批准的方式。后果如上。


解决方案是清理您的资源泄漏。

做到这一点的最佳方法是彻底检查您的代码库,并确保您始终使用try with resources 来管理Connection 对象。

【讨论】:

    猜你喜欢
    • 2016-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多