Tomcat перестает отвечать на запросы JK - PullRequest
10 голосов
/ 17 мая 2010

У меня неприятная проблема с зависшими серверами Tomcat с балансировкой нагрузки. Любая помощь будет принята с благодарностью.

Система

Я запускаю Tomcat 6.0.26 на сервере HotSpot 14.3-b01 (Java 1.6.0_17-b04) на трех серверах, расположенных за другим сервером, который действует как балансировщик нагрузки. Балансировщик нагрузки запускает Apache (2.2.8-1) + MOD_JK (1.2.25). Все серверы работают под управлением Ubuntu 8.04.

В Tomcat настроены 2 разъема: AJP и HTTP. AJP должен использоваться с балансировщиком нагрузки, в то время как HTTP-команда используется командой разработчиков для прямого подключения к выбранному серверу (если у нас есть причина для этого).

У меня на серверах Tomcat установлен Lambda Probe 1.7b, чтобы помочь мне диагностировать и устранить проблему, которая скоро будет описана.

Проблема

Вот проблема: примерно через 1 день серверы приложений работают, JK Status Manager начинает сообщать о состоянии ERR, скажем, для Tomcat2. Он просто застрянет в этом состоянии, и единственное исправление, которое я нашел до сих пор, это ssh the box и перезапуск Tomcat.

Я также должен упомянуть, что JK Status Manager обновляется намного дольше, когда сервер Tomcat находится в этом состоянии.

Наконец, счетчик «Занят» застрявшего Tomcat в JK Status Manager всегда высокий и не будет падать сам по себе - я должен перезапустить сервер Tomcat, подождать, а затем перезагрузить рабочий на JK.

Анализ

Поскольку у меня есть два разъема на каждом Tomcat (AJP и HTTP), я все еще могу подключаться к приложению через HTTP. Приложение работает очень хорошо, как это, очень, очень быстро. Это совершенно нормально, так как я единственный, кто использует этот сервер (поскольку JK прекратил делегировать запросы этому Tomcat).

Чтобы попытаться лучше понять проблему, я взял дамп потока из Tomcat, который больше не отвечает, и из другого, который был перезапущен недавно (скажем, за 1 час до этого).

Экземпляр, который нормально отвечает на JK , показывает большинство потоков TP-ProcessorXXX в состоянии «Runnable» со следующей трассировкой стека:

java.net.SocketInputStream.socketRead0 ( native code )
java.net.SocketInputStream.read ( SocketInputStream.java:129 )
java.io.BufferedInputStream.fill ( BufferedInputStream.java:218 )
java.io.BufferedInputStream.read1 ( BufferedInputStream.java:258 )
java.io.BufferedInputStream.read ( BufferedInputStream.java:317 )
org.apache.jk.common.ChannelSocket.read ( ChannelSocket.java:621 )
org.apache.jk.common.ChannelSocket.receive ( ChannelSocket.java:559 )
org.apache.jk.common.ChannelSocket.processConnection ( ChannelSocket.java:686 )
org.apache.jk.common.ChannelSocket$SocketConnection.runIt ( ChannelSocket.java:891 )
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run ( ThreadPool.java:690 )
java.lang.Thread.run ( Thread.java:619 )

Застрявший экземпляр показывает большинство (все?) Потоков TP-ProcessorXXX в состоянии «Ожидание». Они имеют следующую трассировку стека:

java.lang.Object.wait ( native code )
java.lang.Object.wait ( Object.java:485 )
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run ( ThreadPool.java:662 )
java.lang.Thread.run ( Thread.java:619 ) 

Я не знаю внутренних компонентов Tomcat, но я бы сделал вывод, что потоки "Ожидание" - это просто потоки, сидящие в пуле потоков. Итак, если они являются потоками, ожидающими внутри пула потоков, почему бы Tomcat не заставить их работать с запросами от JK?

РЕДАКТИРОВАТЬ: Я не знаю, нормально ли это, но Lambda Probe показывает мне, в разделе Status, что в состоянии KeepAlive много потоков. Это как-то связано с проблемой, с которой я столкнулся?

Решение

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

Что вызывает эту проблему? Как мне дальше это расследовать? Что я могу сделать, чтобы решить это?

Заранее спасибо.

Ответы [ 4 ]

3 голосов
/ 15 июня 2010

У вас есть настройки памяти JVM и настроенный сборщик мусора? Вы бы сделали это там, где вы установили CATALINA_OPTS

Примеры:

CATALINA_OPTS="$CATALINA_OPTS -server -Xnoclassgc -Djava.awt.headless=true"
CATALINA_OPTS="$CATALINA_OPTS -Xms1024M -Xmx5120M -XX:MaxPermSize=256m"
CATALINA_OPTS="$CATALINA_OPTS -XX:-UseParallelGC"
CATALINA_OPTS="$CATALINA_OPTS -Xnoclassgc"

Существует несколько философий, в которых настройка GC является наилучшей. Это зависит от того, какой код вы выполняете. Вышеприведенный конфиг работал лучше всего для среды с интенсивным использованием JSP (теговые библиотеки вместо инфраструктуры MVC).

2 голосов
/ 06 июня 2010

Проверьте настройки времени активности. Кажется, вы переводите потоки в состояние поддержки активности, и они не истекают. Похоже, ваш сервер не обнаруживает разрыва соединения клиента в течение разумного времени. Есть несколько переменных timeout и count.

1 голос
/ 18 июня 2010

У меня была похожая проблема с Weblogic. Причиной было то, что слишком много потоков ожидали сетевых ответов, а Weblogic не хватало памяти. Tomcat, вероятно, ведет себя так же. Вещи, которые вы можете попробовать:

  • Уменьшите время ожидания ваших подключений.
  • Уменьшите общее количество одновременных подключений, чтобы tomcat не запускал новые потоки при достижении этого количества.
  • Простое исправление, но не устраняет основную причину: возможно, tomcat находится вне памяти, хотя он еще не отображается в журналах. Увеличьте память кота, как описано выше.
1 голос
/ 26 мая 2010

Сначала проверьте файл журнала.

Я думаю, что файл журнала по умолчанию находится в /var/log/daemon.log. (этот файл не содержит только логи от tomcat)

...