2016-11-20 76 views
1

關閉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

回答

0

你提到你沒有使用連接池,但是這可能很好地解決了你在失控線程中看到的問題。

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在內的所有資源? –

0

大量的調試的問題是,在查詢中的一個,我們檢索後上下文沒有關閉它:

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

而且我們在使用後沒有關閉上下文。

關閉上下文解決了問題,修復後沒有線程處於等待狀態。