У меня неприятная проблема с зависшими серверами 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-работника.
Что вызывает эту проблему? Как мне дальше это расследовать? Что я могу сделать, чтобы решить это?
Заранее спасибо.