Приложение scala-play не отвечает

#scala #playframework

#scala #игровая фреймворк

Вопрос:

Я использую приложение scala-Play в рабочей среде. Несколько дней назад я заметил, что из-за высокого уровня процессора на стороне базы данных приложение play начало барахлить, и время отклика увеличилось до нескольких минут. Приложение Play было развернуто на 3 экземплярах EC2, и все они были подключены к ELB. За это время два процесса перестали отвечать, и время отклика увеличилось — до 600 минут (обычно время отклика составляет менее 200 миллисекунд). Из-за большого времени отклика в двух процессах ELB пометил их как неработоспособные, и все запросы были перенаправлены одному процессу (у которого время отклика составляло 20 секунд). Просмотр журналов не сильно помог. После изучения нескольких статей я понял, что взаимоблокировка в пуле потоков может быть одной из причин. Мы использовали пул потоков для блокировки вызовов S3 и неблокирующих вызовов DB. Для этих целей используется другой пул потоков.

 исполнитель { 
 синхронизация = { 
 fork-join-исполнитель { 
 коэффициент параллелизма = 1.0 
 параллелизм - максимум = 24
 }
 }

 асинхронность = { 
 fork-join-исполнитель { 
 коэффициент параллелизма = 1.0 
 параллелизм - максимум = 24
 }
 }
 }

Кто-нибудь может помочь понять, что могло пойти не так? На всех 3 узлах развернута одинаковая сборка, но только два из них перестали отвечать. Уровень процессора на этих не отвечающих узлах составлял менее 10%.

Воспроизведение: 2.5.14 Scala: 2.11.11

Комментарии:

1. Я бы посоветовал вам также изучить возможность использования Akka и Actors. Может оказаться весьма полезным.

Ответ №1:

Есть много вещей, которые могут пойти не так, и это всего лишь игра в угадайку с предоставленной вами информацией.

Я бы начал с создания дампов потоков JVM, которые не отвечают. Если вы записываете журналы консоли вашего приложения, один из способов получить дамп — это отправить сигнал 3 процессу jvm.

Предполагая, что вы запускаете свою службу в среде unix,

 ps aux | grep java 
  

Найдите java pid, на котором запускается ваше приложение play.

 kill -3 <pid>
  

Отправляя сигнал 3 , jvm создает дамп потока в консоли.

Если консоль недоступна, выполните

 jstack -l <pid> >> threaddumps.log
  

Теперь вы сможете увидеть состояние моментального снимка ваших потоков и где оно блокируется, если есть заблокированные потоки.