Tomcat: не удается поместить элементы в очередь запросов

У нас есть приложение Java, работающее на Tomcat (8.0.32), которое периодически прекращает обработку запросов. ЦП делает очень мало, и дамп потока показывает не так много запущенных потоков и большее количество потоков, которые ОЖИДАЮТ (в основном это похоже на потоки в очереди в Tomcat).

Мне кажется, что рабочие процессы Tomcat и опросщики клиентов застряли, но вполне возможно/вероятно, что я неправильно читаю дамп потока. У меня есть clientPoller, который, кажется, ожидает блокировки, предлагая соединение в очередь. Тот же самый замок блокирует любого из рабочих от сбора чего-либо из очереди. Мы не видим ни одного потока, вызывающего блокировку. Ниже приведена трассировка стека ClientPoller + один рабочий процесс (много рабочих процессов с одинаковой трассировкой стека):

"http-nio-8888-ClientPoller-1" #42 daemon prio=5 os_prio=0 tid=0x00007efc9cb86800 nid=0x3367 waiting on condition [0x00007efc5f5f4000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000821e3940> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
    at java.util.concurrent.LinkedBlockingQueue.signalNotEmpty(LinkedBlockingQueue.java:172)
    at java.util.concurrent.LinkedBlockingQueue.offer(LinkedBlockingQueue.java:430)
    at org.apache.tomcat.util.threads.TaskQueue.offer(TaskQueue.java:74)
    at org.apache.tomcat.util.threads.TaskQueue.offer(TaskQueue.java:31)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1361)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:163)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:141)
    at org.apache.tomcat.util.net.AbstractEndpoint.processSocket(AbstractEndpoint.java:934)
    at org.apache.tomcat.util.net.NioEndpoint$Poller.processKey(NioEndpoint.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:810)
    at java.lang.Thread.run(Thread.java:745)
"http-nio-8888-exec-1" #46 daemon prio=1 os_prio=0 tid=0x00007efbb8002000 nid=0x336a waiting on condition [0x00007efc5f2f1000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000000821e3940> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2083)
    at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
    at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:85)
    at org.apache.tomcat.util.threads.TaskQueue.poll(TaskQueue.java:31)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

Вопросы:

  • Ситуация с ClientPoller-1 вообще нормальная? Или это указывает на проблему? Мне кажется, что он застревает, когда объявляет, что очередь не пуста.
  • Этот сценарий звонит в колокола?

С удовольствием загружу весь дамп темы, если это необходимо, и предоставлю любую другую информацию.


person dom_watson    schedule 05.06.2019    source источник


Ответы (1)


Tomcat 8.0.x больше не поддерживается. Если его еще нет в вашем списке TODO, вам следует добавить обновление до версии 8.5.x или 9.0.x — в идеале последней доступной версии любой из них.

Лучше всего предположить, что OutOfMemoryError убьет поток, пока он удерживает блокировку, которую ожидают другие потоки. Теоретически блокировка должна быть снята, но если произойдет OOME, ничего не гарантируется. Я бы проверил ваши журналы на наличие OOME за некоторое время до того, как возникла эта проблема. Если это был OOME, вы можете запустить профилировщик для проверки использования памяти с течением времени, если вашему приложению требуется большая куча.

person Mark Thomas    schedule 06.06.2019
comment
Спасибо, Марк, звучит правдоподобно. Известны ли вам какие-либо другие ошибки потока, кроме OOME, которые вызывают подобное поведение (проверим, но использование памяти кажется довольно стабильным). - person dom_watson; 06.06.2019