【问题标题】:How to monitor where my connections go?如何监控我的连接去向?
【发布时间】:2014-01-29 05:00:46
【问题描述】:

我运行一些 tomcat 应用程序,使用 jndi 连接池。 在某些时候,连接池停止提供连接并且应用程序挂起。 似乎是因为某些代码接收到连接并且没有将其返回到池中。 我如何监控 - 它是哪个代码? 更常见 - 我想看看所有连接目前都在做什么。

我无法更改应用程序。但我可以调整Tomcat,也许添加一些拦截器。

【问题讨论】:

  • 好吧,我倾向于巧妙地应用 Eclipse 的代码搜索功能来找出所有获取连接的代码片段,然后逐一调查。通常问题出在糟糕的错误处理上,比如没有在 finally 子句中关闭连接。
  • 这不合适,代码库非常棒,使用了很多方面和框架。假设琐碎的代码搜索无济于事。
  • 是的,大型代码库需要大量工作。这只是事实。
  • 大多数连接池实现都可以为您监控这一点。如果可以更新池的配置,则可以设置记录“放弃的连接”或“过期的租约”的参数。例如。对于 Tomcat 的 JDBC 连接池,在this 页面上搜索“Abandoned”。
  • 谢谢@vanOekel,这就是我要寻找的!如果您添加单独的答案 - 我将其标记为编写解决方案。

标签: java tomcat jdbc connection-pooling


【解决方案1】:

大多数连接池实现都可以配置为检测未返回池的连接。例如。对于 Tomcat 的 JDBC 连接池,“废弃连接”(租约到期的连接)有多种配置选项。如果您在this 网页上搜索“Abandoned”,您会找到以下选项:

  • 删除已放弃
  • 删除AbandonedTimeout
  • 日志放弃
  • 怀疑超时

正如网页上提到的,这些设置会增加一点开销,但至少您的应用程序不会挂起。在测试您的应用程序时,将removeAbandonedTimeout 设置为较低的值,将maxActive 设置为较低的值,以便您可以及早捕获未返回的连接。

【讨论】:

    【解决方案2】:

    我从不使用连接池 API 本身,我总是将它包装在一个帮助程序中。

    这样,我可以在助手中做到这一点:

    private Exception created = (0 == 1) ? new Exception() : null;
    

    当我遇到像你这样的问题时,我只需更改一个字符 (0 -> 1) 就可以在我的调试器中跟踪谁创建了这个实例。

    【讨论】:

    • 不了解您的解决方案。正如我所写,我无法编辑代码库。即使可以——这有什么帮助? “改变一个字符”是什么意思?
    • Java 不会跟踪谁为您创建了对象。如果你想要这个,你可以尝试Chronon 或更改代码库。上面的代码在连接包装类中。我将0 == 1 更改为1 == 1 并再次编译+部署。更改后,我的连接包装器中有一个堆栈跟踪,告诉我是谁创建了实例。
    • 好的,你建议某种设计模式如何在新应用程序中实现它,从头开始创建它。这显然不是我的情况。
    • 顺便说一下,假设这不是很聪明的模式,因为我们每次都必须重新构建应用程序。正确的解决方案应该可以在不重建的情况下工作。
    • 您可以将(0 == 1) 替换为Boolean.getBoolean() 并使用系统属性来打开和关闭它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 2012-01-04
    相关资源
    最近更新 更多