У меня неприятная проблема с загружаемыми по нагрузке серверами Tomcat, которые висят. Любая помощь будет принята с благодарностью.
Система
Я запускаю Tomcat 6.0.26 на HotSpot Server 14.3-b01 (Java 1.6.0_17-b04) на трех серверах, сидящих за другим сервером, который действует как балансировщик нагрузки. Балансировщик нагрузки запускает Apache (2.2.8-1) + MOD_JK (1.2.25). На всех серверах работает Ubuntu 8.04.
В Tomcat установлены два коннектора: один AJP и один HTTP. AJP должен использоваться с балансировщиком нагрузки, в то время как HTTP используется командой dev для прямого подключения к выбранному серверу (если у нас есть причина для этого).
У меня есть Lambda Probe 1.7b, установленный на серверах Tomcat, чтобы помочь мне быстро диагностировать и исправить проблему.
Проблема
Здесь проблема: примерно через 1 день сервер приложений завершен, JK Status Manager начинает отчет о статусе ERR
для, скажем, Tomcat2. Он просто застрянет в этом состоянии, и единственное исправление, которое я нашел до сих пор, - это ssh box и перезапустить Tomcat.
Я должен также упомянуть, что JK Status Manager занимает намного больше времени, чтобы обновить, когда в этом состоянии сервер Tomcat.
Наконец, подсчет "Занято" застрявшего Tomcat в JK Status Manager всегда высок и не будет снижаться сам по себе - я должен перезапустить сервер Tomcat, подождать, а затем reset рабочий на JK.
Анализ
Так как у меня есть 2 разъема на каждом 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 показывает мне, что в разделе "Состояние" есть много потоков в состоянии KeepAlive
. Это как-то связано с проблемой, которую я испытываю?
Решение?
Итак, как я уже говорил ранее, единственным исправлением, которое я нашел, является остановка экземпляра Tomcat, остановка рабочего JK, ожидание последнего занятого подсчета, медленное падение, запуск Tomcat и включение рабочего стола JK один раз еще раз.
Что вызывает эту проблему? Как я должен его расследовать? Что я могу сделать для его решения?
Спасибо заранее.