Огромная разница во времени поиска JNDI - PullRequest
7 голосов
/ 30 августа 2011

Мы испытываем огромные различия во времени отклика в устаревшем веб-приложении J2EE, работающем на Weblogic 10.3. Система состоит из двух экземпляров сервера Weblogic (внешнего и внутреннего), которые работают на одном физическом сервере, и базы данных Oracle, работающей на отдельном хосте. Внешний инструмент измерения предупреждает нас каждый раз, когда вход в систему занимает более четырех секунд. В последнее время эти предупреждения были частыми. Просмотр журнала, написанного сервлетом, обрабатывающим запросы на вход, показывает, что время, потраченное на вызов EJB от внешнего интерфейса к внутреннему.

Пример измеренного времени:

time    ms   
8:40:43 25
8:42:14 26
8:44:04 26
8:44:25 26
8:44:47 26
8:46:06 26
8:46:41 7744
8:47:00 27
8:47:37 27
8:49:00 26
8:49:37 26
8:50:03 8213
8:50:57 27
8:51:04 26
8:51:06 25
8:57:26 2545
8:58:13 26
9:00:06 5195

Как видно, большинство запросов (70%, взятых из более крупной выборки) выполняются своевременно, но значительная их часть занимает очень много времени.

Шаги, выполняемые в течение измеренного времени, следующие:

  • Поиск JNDI сессионного компонента, предлагающего интерфейс аутентификации (внешний интерфейс)
  • Вызов метода аутентификации сессионного компонента (frontend-> backend)
  • Резервирование JDBC-соединения из пула соединений (бэкэнд)
  • Выполнение запроса к пользовательской базе данных (размер таблицы очень умеренный, и таблица должна быть правильно проиндексирована) (бэкэнд)
  • Чтение набора результатов, создание пользовательского объекта POJO (бэкэнд)
  • Возвращение объекта пользователя POJO (backend-> frontend)

Нагрузка на серверную машину очень мала (99% простоя), а количество пользователей очень умеренное. Количество свободной памяти, сообщаемое Weblogic, варьируется от 60% до 90% на обоих серверах. Сборка мусора записана. Основные коллекции редки и заканчиваются за 2-3 секунды, когда они появляются. Кроме того, основные явления ГХ, по-видимому, не происходят одновременно с длительным временем отклика. Длительное время отклика происходит в часы занятости и в нерабочее время. Максимальный размер пула соединений JDBC в настоящее время установлен равным 80, что превышает количество одновременных пользователей.

Обновление:

Получено разрешение на перезагрузку системы с добавлением дополнительной регистрации производительности. Журнал ясно показывает, что поиск JNDI - это та часть, где тратится время:

03:01:23.977 PERFORMANCE: looking up foo.bar.Bar from JNDI took 6 ms
03:14:47.179 PERFORMANCE: looking up foo.bar.Bar from JNDI took 2332 ms
03:15:55.040 PERFORMANCE: looking up foo.bar.Bar from JNDI took 1585 ms
03:29:25.548 PERFORMANCE: looking up foo.bar.Bar from JNDI took 7 ms
03:31:09.010 PERFORMANCE: looking up foo.bar.Bar from JNDI took 6 ms
03:44:25.587 PERFORMANCE: looking up foo.bar.Bar from JNDI took 6 ms
03:46:00.289 PERFORMANCE: looking up foo.bar.Bar from JNDI took 7 ms
03:59:28.028 PERFORMANCE: looking up foo.bar.Bar from JNDI took 2052 ms

Просмотр журналов GC внешнего и внутреннего интерфейсов показывает, что GC не выполняется, когда происходит медленный поиск JNDI.

Контекст создается следующим образом при создании сеанса:

Hashtable ht = new Hashtable();
ht.put(Context.PROVIDER_URL, url);
ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
jndiContext = new InitialContext(ht);

где url - это URL-адрес t3, указывающий на DNS-имя и порт внутреннего сервера. Это должно быть хорошо, верно?

Первое, что нужно вспомнить, - это кэшировать ссылки, полученные из JNDI, по крайней мере, это был предпочтительный путь 10 лет назад ... Но разве реализация InitialContext в Weblogic уже не выполняет это кэширование, или она действительно извлекается ссылка с внутреннего сервера на каждый звонок?

Что может быть причиной частых медленных поисков JNDI? Есть ли обходной путь для этого (например, поможет ли кэширование ссылок)?

Ответы [ 3 ]

6 голосов
/ 30 августа 2011

Так что может быть причиной этого довольно странного поведения?

Все, что мы скажем, может быть предположением.Вместо того, чтобы играть в эту игру, вот несколько советов для исследования проблемы:

  • Попробуйте использовать профилировщик, чтобы узнать, на что тратится время.
  • Попробуйте использовать сетевой инструмент (например,WireShark), чтобы увидеть, есть ли аномальный сетевой трафик.
  • Добавьте запись / трассировку в ключевых точках, чтобы увидеть, куда идет время.
  • Найдите Thread.sleep(...) вызовы.(Упс ... это предположение.)
2 голосов
/ 30 августа 2011

Как говорит Стефан, некоторые из них являются догадками без адекватных операторов записи между ними.Вы четко перечислили каждый элемент в транзакции, но я предполагаю, что у вас нет logger.debug, который вы можете включить и который имеет временные метки.

Некоторые вопросы, на которые стоит посмотреть:

Сколько бинов в пуле для каждого внешнего и внутреннего бинов - это должен быть max-beans-in-free-pool элемент weblogic-ejb-jar.xml

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

Точно так же на фронте JDBC вы можете использовать консоль Weblogic для отслеживания любых конфликтов с получением соединений. Ударяете ли вы о высоких показателях и ожиданиях на вкладке JDBC Monitoring?Это должно быть следующее, что нужно проверить.

2 голосов
/ 30 августа 2011

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

...