2009-07-16 63 views
6

我有使用LDAP進行身份驗證的JBoss應用程序服務器。最近我們注意到有很多緩慢的請求(> 15秒)。掛起15秒的LDAP請求

我做了服務器的一些threaddumps,發現在那裏等待鎖的線程:[email protected]

java.lang.Object.wait(Native Method) 
com.sun.jndi.ldap.Connection.readReply(Connection.java:418) 
com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:340) 
com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:192) 
com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2637) 
com.sun.jndi.ldap.LdapCtx.(LdapCtx.java:283) 
com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175) 
com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:134) 
com.sun.jndi.url.ldap.ldapURLContextFactory.getObjectInstance(ldapURLContextFactory.java:35) 
javax.naming.spi.NamingManager.getURLObject(NamingManager.java:584) 

所有我見過的請求已被中在這種狀態下等待已經用了15秒以上完成。我們正在監控LDAP服務器,監控工具的所有請求在不到200毫秒內完成。這讓我覺得這是com.sun.jndi.ldap代碼的問題。反編譯的com.sun.jndi.ldap.Connection類(jdk1.5.0_12)我看到這一點:

BerDecoder readReply(LdapRequest ldaprequest) throws IOException, NamingException 
{ 
_L2: 
    BerDecoder berdecoder; 
    if((berdecoder = ldaprequest.getReplyBer()) != null) 
    break; /* Loop/switch isn't completed */ 
    try 
    { 
label0: 
    { 
     synchronized(this) 
     { 
     if(sock == null) 
      throw new ServiceUnavailableException((new StringBuilder()).append(host).append(":").append(port).append("; socket closed").toString()); 
     } 
     synchronized(ldaprequest) 
     { 
     berdecoder = ldaprequest.getReplyBer(); 
     if(berdecoder == null) 
     { 
      ldaprequest.wait(15000L); 
      break label0; 
     } 
     } 
     break; /* Loop/switch isn't completed */ 
    } 
    } 
    ... 

有明顯的15000毫秒的硬編碼超時。

有沒有人有任何解決方法/解決方法的想法?

+0

berdecoder爲什麼會爲空?一個相關的思想:當DNS服務器不可用時,許多名稱解析器客戶端上的默認超時值爲15秒。 – mas 2009-07-16 14:58:01

回答

0

在我看來,好像它只在回覆爲空時纔會等待 - 想知道是否存在某種版本不匹配,導致您的應用無法解析來自服務器的回覆。

您是否嘗試過附加源代碼,並且看到您可以在eclipse中設置斷點。

-ace

0

我見過使用LDAP時連接到ActiveDirectory中框(當網絡中有不止一個服務器)之前是這樣的。它最終成爲一個DNS問題,我們只需要沖洗我們的DNS緩存(在Windows框中的「ipconfig/flushdns」)。這可能是也可能不是你的問題,只是認爲它值得一試。

1

this bug類似的聲音,您是否嘗試過使用數據包嗅探器檢查網絡流量以檢查此情況?

1

您正在使用舊的jdk1.5(jdk1.5.0_12)。

我與使用tomcat 5.5的jdk1.5_16有同樣的問題。我們有一個線程正在等待一個ldap響應,它阻塞了所有其他線程,因爲我不知道JBoss,但是在tomcat中至少所有的ldap認證都是按順序完成的。

如果您查看粘貼的反編譯代碼,等待15秒鐘後,您將有一箇中斷label0,這實際上是一個循環。所以它會循環直到ldap回答(沒有超時!)。

我不知道在哪個版本,它是固定的,但在1.5.0_22代碼是現在:

BerDecoder readReply(LdapRequest paramLdapRequest) 
    throws IOException, NamingException 
{ 
    BerDecoder localBerDecoder; 
    int i = 0; 

    while (((localBerDecoder = paramLdapRequest.getReplyBer()) == null) && (i == 0)) { 
    try 
    { 
     synchronized (this) { 
     if (this.sock == null) { 
      throw new ServiceUnavailableException(this.host + ":" + this.port + "; socket closed"); 
     } 
     } 

     synchronized (paramLdapRequest) 
     { 
     localBerDecoder = paramLdapRequest.getReplyBer(); 
     if (localBerDecoder == null) 
      if (this.readTimeout > 0) 
      { 
      paramLdapRequest.wait(this.readTimeout); 
      i = 1; 
      } else { 
      paramLdapRequest.wait(15000L); 
      } 
     else 
      break label163: 
     } 
    } 
    catch (InterruptedException localInterruptedException) { 
     throw new InterruptedNamingException("Interrupted during LDAP operation"); 
    } 

} 

所以,現在,如果你提供的超時值,將等待時間,然後退出循環。這應該解鎖認證隊列。