LDAP-запросы зависают на 15 секунд - PullRequest
6 голосов
/ 16 июля 2009

У меня есть сервер приложений JBoss, который использует LDAP для аутентификации. В последнее время мы заметили, что много медленных запросов (> 15 секунд).

Я сделал несколько потоков на сервере и заметил, что многие потоки ожидают блокировки: com.sun.jndi.ldap.LdapRequest@54ceac

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 миллисекунд.

У кого-нибудь есть идеи для исправления / обходного пути?

Ответы [ 4 ]

1 голос
/ 20 июня 2011

Вы используете старый jdk1.5 (jdk1.5.0_12).

У меня та же проблема с jdk1.5_16 при использовании tomcat 5.5. У нас есть поток, который ожидает ответа 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");
     }

 }

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

1 голос
/ 26 декабря 2009

Похоже на эту ошибку , вы пытались проверить сетевой трафик с помощью анализатора пакетов, чтобы проверить это условие?

0 голосов
/ 08 августа 2009

Я видел нечто подобное раньше при использовании LDAP для подключения к коробке ActiveDirectory (в сети, где имеется более одного сервера). В результате возникла проблема с DNS, и нам просто нужно было очистить кэш DNS («ipconfig / flushdns» в окне Windows). Это может или не может быть вашей проблемой, просто подумал, что стоит попробовать.

0 голосов
/ 20 июля 2009

выглядит так, как будто он ожидает только, если ответ нулевой - интересно, есть ли какое-то несоответствие версий, которое приводит к тому, что ваше приложение не может проанализировать ответ с вашего сервера.

Вы пытались подключить источник, и видите, что можете установить точку останова в затмении.

* 1005-ACE *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...