TequilaOne
@TequilaOne

Как избавиться от плодящихся threads (java потомки) в Linux при использовании бекенда на Kotlin (Ktor + Coroutines)?

Есть бекенд, (парсер) написанный на Kotlin (фреймворк Ktor + Coroutines + PostgreSQL + Redis) и скомпилированный в jar.
Проблема заключается в том, что постепенно нарастают threads ( если смотреть в htop , то это thr).
Запускаю в терминале парсер командой
sudo java -Xmx256m -Xms256m -jar zeon-backend-0.0.1-all.jar -Xopt-in=kotlin.RequiresOptIn. parser >build/zeon-parser.log 2>&1 &

Захожу спустя день в утилиту htop, а там отображает порой до 3000 thr
62de60a5e316e555080542.png
При этом память (озу) не утекает практически, все возможные открытые транзакции с postgres закрываются и не накапливаются, с редисом тоже всё хорошо.

Если кратко, то "парсер" ходит по аудио потокам (интернет радио станции), посредством http запросов (okhttp3) и потом все соединения и чтение потока закрывается.
Запускаю парсер в корутинах, в скоупе на Dispatcher.IO потоке. Да собственно как только я уже его не запускал, одна и та же ситуация. Спустя день если зайти - пара тысяч thr накапливается.

Также мониторил через VisualVM. Ничего сверхъестественного там не увидел. В какую сторону копать, понятия не имею. Не особо хочется делать костыль, аля крашить парсер в коде спустя n кол-во времени и перезапускать автоматом с помощью юнита systemd..
  • Вопрос задан
  • 222 просмотра
Пригласить эксперта
Ответы на вопрос 1
mayton2019
@mayton2019
Bigdata Engineer
Несколько мыслей. Не претендует на правильность. Особенностей Котлин не знаю но подозреваю что он под капотом просто использует Java Threads.

1) Java используют модель потоков при коророй 1 поток ОС не равен потоку JVM. Обычно 1 поток ОС может обслуживать много Java threads. В состоянии покоя threads мало потребляют ресурсов.

2) Я пока не вижу проблем до тех пор пока у вас нет нехватки Heap. 1 Thread по умолчанию аллоцирует 1Мб поэтому 1000 тредов могут у вас скушать гигабайт. Есть опция командной строки которая это регулирует. Ее надо трогать аккуратно чтоб не получить другую ошибку типа Stackoverflow.

3) По поводу того чем заняты threads. Сделайте дамп стека потоков как один чел тут пишет https://www.baeldung.com/java-thread-dump

И посмотрите на вершине стека какую функцию каждый поток выполняет. Если например они друг друга блокируют или ждут I/O - это будет повод поговорить с программистом. Может код написан неоптимально.

4) Кроме того программист должен был заложить в конфиги регулятор числа рабочик потоков в пуле. Это может быть нечто вроде

Executors.newFixedThreadPool(....);

короче поищите в сорцах. Если не заложил - попросите пускай сделает это property.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы