100 потоков TIMED_WAITING в tomcat, что приводит к его остановке, когда общее количество потоков превышает 200

Недавно один из наших производственных серверов tomcat перестал отвечать, потому что количество занятых потоков tomcat достигло 200. Когда мы сделали дамп потока перед перезапуском, мы получили 100 потоков в состоянии TIMED_WAITING, таких как эти 3 потока:

""http-bio-7007"-exec-241" daemon prio=10 tid=0x00002aaab107b000 nid=0x59df waiting on condition [0x0000000051239000]
java.lang.Thread.State: TIMED_WAITING (parking)
   at sun.misc.Unsafe.park(Native Method)
   - parking to wait for  <0x0000000580d877d0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
   at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
   at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
   at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:424)
   at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:86)
   at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:32)
   at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
   at java.lang.Thread.run(Thread.java:662)

""http-bio-7007"-exec-237" daemon prio=10 tid=0x00002aaab186e000 nid=0x596d waiting on condition [0x000000004d1f9000]
java.lang.Thread.State: TIMED_WAITING (parking)
   at sun.misc.Unsafe.park(Native Method)
   - parking to wait for  <0x0000000580d877d0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
   at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
   at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
   at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:424)
   at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:86)
   at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:32)
   at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
   at java.lang.Thread.run(Thread.java:662)

""http-bio-7007"-exec-236" daemon prio=10 tid=0x00002aaab1118000 nid=0x596c waiting on condition [0x000000004e50c000]
java.lang.Thread.State: TIMED_WAITING (parking)
   at sun.misc.Unsafe.park(Native Method)
   - parking to wait for  <0x0000000580d877d0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
   at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
   at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
   at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:424)
   at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:86)
   at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:32)
   at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
   at java.lang.Thread.run(Thread.java:662)

У нас есть 4 пула потоков приложений (например, pool-4-thread-20 и т. д.), каждый из которых имеет по 20 потоков, поэтому я не уверен, в какой очереди блокировки ожидают эти 100 потоков? Мы используем пул соединений c3P0 со спящим режимом, который, похоже, не является причиной этого.

Есть идеи, что такое java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject?


person ThinkFloyd    schedule 04.06.2012    source источник
comment
Пробовали ли вы взять дамп кучи и запустить его через MAT, чтобы увидеть, какие объекты накапливаются?   -  person Bruno Grieder    schedule 04.06.2012
comment
На данный момент у нас такая же проблема. Даже перезапуск кота не помог. После перезагрузки все снова заработало. СТРАННЫЙ! плохо исследую дальше и сообщу, если я найду что-то интересное.   -  person Janning    schedule 01.07.2012
comment
Это не имеет никакого отношения к спящему режиму, поскольку сегодня вечером мы столкнулись с этой проблемой на всей нашей ферме серверов, и некоторые из них являются просто серверами изображений без спящего режима или стека базы данных.   -  person Janning    schedule 01.07.2012
comment
Наша проблема была связана с ошибкой дополнительной секунды. перезагрузка сервера лечит. некоторый отчет о перезапуске ntp тоже поможет. см. здесь serverfault.com/questions/403732/   -  person Janning    schedule 01.07.2012
comment
Это было исправлено, когда мы исправили наш код, из-за которого происходила утечка соединений с БД, управляемых c3p0. В нашем коде было несколько потоков, в которых мы не вызывали rollback() специально в блоке catch перед закрытием диспетчера сущностей в блоке finally, поэтому в случае исключений соединение не возвращалось в пул, и если частота исключений высока (больше, чем размер пула в течение интервала времени ожидания), тогда все остальные потоки процесса будут накапливаться, чтобы получить соединение.   -  person ThinkFloyd    schedule 04.07.2012
comment
Это такой плохо написанный вопрос, и он наверняка смутит многих людей, читающих его и связанные с ним ответы. TIMED_WAITING (парковка) — это именно то, что вы увидите в потоках, ожидающих соединения. Я бы хотел, чтобы этот вопрос можно было удалить, чтобы сэкономить значительное количество потраченного времени, поскольку многие люди в конечном итоге его читают.   -  person stepanian    schedule 10.08.2014


Ответы (2)


Это было исправлено, когда мы исправили наш код, из-за которого происходила утечка соединений с БД, управляемых c3p0. В нашем коде было несколько потоков, в которых мы не вызывали rollback() специально в блоке catch перед закрытием диспетчера сущностей в блоке finally, поэтому в случае исключений соединение не возвращалось в пул, и если частота исключений высока (больше, чем размер пула в течение интервала времени ожидания), тогда все остальные потоки процесса будут накапливаться, чтобы получить соединение.

person ThinkFloyd    schedule 30.11.2012
comment
У меня такая же проблема, не могли бы вы помочь мне, как использовать соединение? Так что он не может получить утечку. - person Mohanraj; 21.04.2016

Есть идеи, что такое java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject?

ConditionObject используется внутри очереди для синхронизации доступа к очереди разными потоками.

Это стандартная трассировка стека, когда поток вашего исполняющего пула простаивает и ожидает новых задач.

person Mirko    schedule 30.07.2012