2016-11-20 2 views
1

После закрытия Tomcat мы увидели много ошибок относительно возможной утечки памяти, поскольку Tomcat не смог остановить поток. Согласно Tomcat, у нас было ~ 2600 потоков демона, которые ждут в com.sun.jndi.ldap.Connection.pauseReader.Соединения LDAP не закрываются при использовании LdapTemplate

Мы используем LdapTemplate для чтения данных из LDAP. LdapTemplate создается каждый раз, когда нам нужно читать данные из LDAP. Из документации я вижу, что все ресурсы освобождаются LdapTemplate после завершения поиска. Мы не включили объединение для LdapTemplate, а значение по умолчанию - false.

После отладки это выглядит так, что потоки, созданные для соединения, не уничтожаются сразу после завершения поиска, но некоторые из них в конечном итоге уничтожаются.

Любая идея, почему у нас будет так много потоков демона, ожидающих на 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); 

Update: После настройки объединены истина соединения высвобождаются в порядке.

ldapContextSource.setPooled(true); 

Проблема в том, что мы не можем использовать пул. Я до сих пор не понимаю, почему, когда не используется пул, соединения не выпущены должным образом.

+0

Можно ли привести пример использования LdapTemplate, Spring версии и таких вещей, это может быть полезно – karelss

ответ

0

Вы упоминаете, что вы не используете пул соединений, но это вполне может решить проблему, с которой вы сталкиваетесь с беглыми потоками.

Take a look here о том, как настроить объединение пула LDAP с помощью конфигурации Spring XML с помощью PoolingContextSource. Here is another example о том, как включить объединение пулов с помощью аннотационной конфигурации.

Обратите внимание, что в документации упоминается специально, чтобы включить объединение в Spring LDAP, а не JNDI LDAP-провайдера в JDK через свойство "com.sun.jndi.ldap.connect.pool".

Для справки, здесь аналогичная проблема с 2013 года, когда он появляется что позволяет пулы соединений удалось уменьшить количество потоков: https://github.com/spring-projects/spring-security/issues/2397

+0

К сожалению, мы не можем использовать пул каждый раз, когда учетные данные могут отличаться, поэтому соединения не могут быть повторно использованы. Кроме того, мы используем GSSAPI для аутентификации и TLS, поэтому в соответствии с пулом подключения документации не будет работать должным образом. Я видел проблему с 2013 года, но я не уверен, что понимаю, почему пул помог. Должно ли LdapTemplate закрыть все ресурсы, включая Connection после поиска? –

0

После много отладки вопроса было то, что в одном из запросов, которые мы извлекаться контекст без его закрытия:

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

И мы не закрывали контекст после использования.

Закрытие контекста решило проблему, ни один из них не находится в состоянии ожидания после исправления.