Как восстановить соединение при перезапуске сервера LDAP? - PullRequest
8 голосов
/ 09 января 2012

У меня есть ситуация, когда с помощью Java-программы я создаю javax.naming.ldap.LdapContext и выполняю над ним операцию search(), которая устанавливает базовое соединение. Затем я помещаю поток приложений Java в спящий режим, во время которого я перезагружаю сервер LDAP (OpenLDAP, только для заметки). Когда поток приложения просыпается и пытается выполнить какую-либо операцию с LdapContext, созданным ранее, он выдает "CommunicationException: Connection is closed".

То, что я хочу, это возможность восстановить соединение.

Я вижу, что LdapContext имеет метод reconnect() - где я передаю управление как null. Однако это не имеет никакого эффекта. То, что я увидел в реализации LDAP Sun, это то, что во время перезапуска сервера LDAP, ConnectionPool, поддерживаемый реализацией Sun, помечал базовый экземпляр com.sun.jndi.ldap.LdapClient как «usable = false». При reconnect() вызове - он просто вызывает ensureOpen(), который снова проверяет, является ли флаг usable false или нет - если это false; затем бросает CommunicationException - так что вернемся к исходной точке.

Мой вопрос: как приложение Java выдерживает перезагрузку внешнего сервера LDAP? Является ли создание нового LdapContext снова единственным выходом? Цените любые идеи.

Вот трассировка стека исключения:

javax.naming.CommunicationException: connection closed [Root exception is java.io.IOException: connection closed]; remaining name 'uid=foo,ou=People,dc=example,dc=com'
at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1979)
at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1824)
at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1749)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:368)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:338)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:321)
at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:248)
Caused by: java.io.IOException: connection closed
at com.sun.jndi.ldap.LdapClient.ensureOpen(LdapClient.java:1558)
at com.sun.jndi.ldap.LdapClient.search(LdapClient.java:504)
at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1962)
... 26 more

Ответы [ 4 ]

2 голосов
/ 04 августа 2013

Просто включите пул соединений JNDI, и все это позаботится о вас за кулисами. См. Руководство по функциям JNDI и документацию поставщика LDAP. Он контролируется всего несколькими свойствами.

0 голосов
/ 11 февраля 2013

Следует заметить, что это в основном связано с пулами соединений LDAP.Как определено здесь :

Соединение извлекается из пула, используется, возвращается в пул, а затем снова извлекается из пула для другого экземпляра контекста.

Таким образом, повторное использование предыдущего соединения может вызвать такую ​​проблему:

Вы можете проверить поведение без использования пула подключений LDAP, установив

com.sun.jndi.ldap.connect.pool=false

Также возможна другаяпричиной может быть тайм-аут чтения операций LDAP.Фактически, операция чтения не уведомляется о закрытии сервера LDAP после определенного времени ожидания.Для получения дополнительной информации, вы можете взглянуть на эту ссылку

0 голосов
/ 03 августа 2013

У нас была эта проблема на работе.Решение, которое мы придумали (возможно, не самый лучший ответ).Был создан сторожевой поток, который проверял бы соединение с некоторой фиксированной скоростью.Если соединение не работает, оно повторно инициализирует соединение с LDAP.

0 голосов
/ 09 января 2012

UnboundID LDAP SDK предоставляет средства для автоматического подключения, когда операция автоматического повторного подключения невидима для клиента.

...