2009-07-16 5 views
6

Tôi có máy chủ ứng dụng JBoss đang sử dụng LDAP để xác thực. Gần đây chúng tôi đã nhận thấy rằng có rất nhiều yêu cầu chậm (> 15 giây).Yêu cầu LDAP treo trong 15 giây

tôi đã làm một số threaddumps của máy chủ và nhận thấy rằng nhiều chủ đề mà chờ đợi vào một khóa: [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) 

Tất cả các yêu cầu Tôi đã thấy rằng đã chờ đợi ở trạng thái này đã sử dụng hơn 15 giây để hoàn thành. Chúng tôi đang giám sát máy chủ LDAP và tất cả các yêu cầu từ công cụ giám sát kết thúc trong vòng chưa đầy 200 ms. Điều này làm cho tôi nghĩ rằng đây là một vấn đề với mã com.sun.jndi.ldap. Dịch ngược lớp com.sun.jndi.ldap.Connection (jdk1.5.0_12) Tôi thấy điều này:

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 */ 
    } 
    } 
    ... 

Có vẻ như là một thời gian chờ hardcoded của 15000 mili giây.

Có ai có ý tưởng nào để sửa chữa/giải quyết sự cố không?

+0

Tại sao berdecoder lại là null? Một suy nghĩ liên quan: thời gian chờ mặc định trên nhiều máy khách phân giải tên khi máy chủ DNS không khả dụng là 15 giây. – mas

+0

Sự cố mạng? Bạn sẽ ngạc nhiên về mức độ thường xuyên của một switch sẽ thả các gói ngay cả trên một mạng LAN đơn giản – nos

Trả lời

0

trông giống như tôi chỉ đợi câu trả lời là không có gì - tự hỏi liệu có một số loại phiên bản không phù hợp khiến ứng dụng của bạn không thể phân tích cú pháp câu trả lời từ máy chủ của bạn hay không.

Bạn đã thử gắn nguồn và thấy bạn có thể đặt điểm ngắt trong nhật thực.

-ace

0

Tôi đã nhìn thấy một cái gì đó như thế này trước khi sử dụng LDAP để kết nối với một hộp ActiveDirectory (trong một mạng, nơi có nhiều hơn một máy chủ). Nó đã kết thúc là một vấn đề DNS và chúng tôi chỉ cần xóa bộ nhớ cache DNS của chúng tôi ("ipconfig/flushdns" trên một cửa sổ hộp). Điều này có thể hoặc có thể không phải là vấn đề của bạn, chỉ cần nghĩ rằng nó sẽ có giá trị một thử.

1

Âm thanh tương tự như this bug, bạn đã thử kiểm tra lưu lượng mạng với gói sniffer để kiểm tra điều kiện này chưa?

1

Bạn đang sử dụng một jdk1.5 cũ (jdk1.5.0_12).

Tôi gặp vấn đề tương tự với jdk1.5_16 sử dụng tomcat 5.5. Chúng tôi có một chủ đề đó là chờ đợi một phản ứng ldap và nó chặn tất cả các chủ đề khác bởi vì tôi không biết về JBoss nhưng trong tomcat ít nhất là tất cả các xác thực ldap được thực hiện tuần tự.

Nếu bạn nhìn vào mã được biên dịch mà bạn đã dán, sau khi đợi 15 giây bạn có một nhãn ngắt 0 có hiệu quả là một vòng lặp. Vì vậy, nó sẽ lặp lại cho đến khi trả lời ldap (không có thời gian chờ!).

Tôi không chắc chắn trong đó phiên bản nó đã được cố định, nhưng trong 1.5.0_22 mã bây giờ là:

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"); 
    } 

} 

Vì vậy, bây giờ, nếu bạn cung cấp một giá trị thời gian chờ nó sẽ đợi cho thời điểm đó, và sau đó thoát khỏi vòng lặp. Điều này sẽ mở khóa hàng đợi xác thực.