使用LdapTemplate时LDAP连接未关闭

问题描述:

关闭Tomcat后,我们发现很多关于可能的内存泄漏的错误,因为Tomcat未能停止线程。 根据Tomcat,我们在com.sun.jndi.ldap.Connection.pauseReader中有2600个daemon线程正在等待。使用LdapTemplate时LDAP连接未关闭

我们使用LdapTemplate从LDAP读取数据。每次我们需要从LDAP读取数据时都会创建LdapTemplate。从文档中我看到所有的资源都是在搜索结束后由LdapTemplate发布的。 我们尚未为LdapTemplate启用池,默认值为false。

调试后,它看起来为Connection创建的线程在搜索结束后不会立即销毁,而是最终销毁一些线程。

任何想法为什么我们会有这么多守护线程等待com.sun.jndi.ldap.Connection.pauseReader?

我们使用的是spring-ldap 2.0.2.RELEASE。我们如何执行搜索之前创建LdapTemplate

示例代码:

LdapContextSource contextSource = new LdapContextSource(); 
SimpleAuthenticationSource authenticationSource = new SimpleAuthenticationSource(userDn, password); 
contextSource.setAuthenticationSource(authenticationSource); 
LdapTemplate ldapTemplate = new LdapTemplate(contextSource); 
ldapTemplate.setIgnorePartialResultException(true); 

更新: 汇集设置为true后的连接都被释放确定。

ldapContextSource.setPooled(true); 

问题是我们不能使用池。我仍然不明白为什么不使用连接池时连接没有正确释放。

+0

你可以举一个例子,你如何使用LdapTemplate,Spring版本和那种东西,它可以是有用的 – karelss

你提到你没有使用连接池,但是这可能很好地解决了你在失控线程中看到的问题。

Take a look here如何通过配置PoolingContextSource的Spring XML配置来配置LDAP连接池。 Here is another example如何使用基于注释的配置启用连接池。

请注意,文档专门提到在Spring LDAP中启用池,而不是通过"com.sun.jndi.ldap.connect.pool"属性在JDK中提供JNDI LDAP提供程序。

供参考,在这里是从2013年开始了类似的问题,即它似乎使连接池能够减少线程数:https://github.com/spring-projects/spring-security/issues/2397

+0

不幸的是,我们不能使用池,因为每次证书可能会有所不同,因此连接无法重用。另外,我们使用GSSAPI进行身份验证和TLS,因此根据文档连接池将无法正常工作。 我从2013年就看到了这个问题,但我不确定我是否理解为什么游泳池有帮助。搜索后不应该LdapTemplate关闭包括Connection在内的所有资源? –

大量的调试的问题是,在查询中的一个,我们检索后上下文没有关闭它:

ldapTemplate.getContextSource().getReadOnlyContext().getNameInNamespace() 

而且我们在使用后没有关闭上下文。

关闭上下文解决了问题,修复后没有线程处于等待状态。