重新启动LDAP服务器时如何重新连接?

时间:2012-01-09 11:17:20

标签: java exception ldap reconnect

我有一种情况,通过Java程序,我创建一个javax.naming.ldap.LdapContext并对其进行search()操作 - 这将构成一个底层连接。然后我将Java应用程序线程置于休眠状态,在此期间我重新启动LDAP服务器(OpenLDAP,只需注意)。当App线程唤醒并尝试对之前创建的LdapContext执行任何操作时,它会抛出“CommunicationException: Connection is closed”。

我想要的是能够重新建立连接。

我看到LdapContextreconnect()方法 - 我将控件作为null传递。但是,这没有任何效果。我在Sun LDAP实现中看到,在重新启动LDAP服务器期间,Sun实现维护的ConnectionPool标记了底层com.sun.jndi.ldap.LdapClient实例,其中包含“useful = 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 个答案:

答案 0 :(得分:2)

只需启用JNDI连接池,它就会在幕后为您完成。请参阅JNDI功能指南和LDAP提供程序文档。它仅由几个属性控制。

答案 1 :(得分:0)

UnboundID LDAP SDK提供了一种自动连接方式,其中自动重新连接操作对客户端是不可见的。

答案 2 :(得分:0)

我们在工作中遇到了这个问题。我们提出的解决方案(可能不是最好的答案)。是创建一个看门狗线程,以固定的速率检查连接。如果连接不起作用,它将重新初始化与LDAP的连接。

答案 3 :(得分:-1)

您应该注意,这主要与LDAP连接池有关。根据定义here

  

从池中检索连接,使用,返回到池,然后再从池中检索另一个Context实例。

因此,重复使用先前的连接可能会导致此类问题:

您可以通过设置

来测试不使用LDAP连接池的行为
com.sun.jndi.ldap.connect.pool=false

另外,另一个可能的原因可能是读取LDAP操作的超时。实际上,在特定超时后,不会通知读取操作关闭LDAP服务器。有关详细信息,请查看this link