【问题标题】:How to reconnect when the LDAP server is restarted?LDAP服务器重启后如何重新连接?
【发布时间】:2012-02-05 22:30:51
【问题描述】:

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

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

我看到LdapContext 有一个reconnect() 方法——我将控件传递为null。但是,这没有任何效果。我在 Sun LDAP 实现中看到,在 LDAP 服务器重新启动期间,由 Sun 实现维护的 ConnectionPool 将底层 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

【问题讨论】:

  • 如果您没有更改任何绑定用户,我认为重启服务器后应该不会出现问题。
  • 您好 Imran,很遗憾 - 在 LDAP 服务器重新启动后,LdapContext 上的所有操作都失败并出现 CommunicationException。
  • 您能否分享一些代码,您是如何创建连接并使用它进行搜索的?
  • 我正在使用 Active Directory。我重新启动服务器并搜索。它没有给我任何异常并且搜索完成。
  • @Anand:我遇到了和你一样的问题。由于 Jan 13 没有活动,看来您已经找到了解决方案。如果您与我们分享,我将不胜感激。谢谢

标签: java exception ldap reconnect


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        您应该注意,这本质上与 LDAP 连接池有关。如定义here:

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

        因此,重用以前的连接可能会导致这样的问题:

        您可以通过设置不使用 LDAP 连接池来测试行为

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

        另外,另一个可能的原因可能是读取 LDAP 操作超时。实际上,在特定超时后,不会通知读取操作关闭 LDAP 服务器。想了解更多可以关注this link

        【讨论】:

        • 连接池默认关闭。我不能从你的最后一段中理解多少。如果服务器在读取期间出现故障,您肯定会收到通知。
        猜你喜欢
        • 2016-07-23
        • 1970-01-01
        • 1970-01-01
        • 2022-08-24
        • 2013-11-10
        • 1970-01-01
        • 1970-01-01
        • 2011-09-14
        • 2011-04-21
        相关资源
        最近更新 更多