Форум на Kuban.ru (http://forums.kuban.ru/)
-   Разработка программ (http://forums.kuban.ru/f1024/)
-   -   spring-приложение зависает (http://forums.kuban.ru/f1024/spring-prilozhenie_zavisaet-8309934.html)

Добрых дел мастер 06.05.2017 22:24

spring-приложение зависает
 
У меня тут вопрос возник. Spring-приложение(сервер - tomcat) перестает принимать соединения. Точнее, соединение устанавливается, но обмен данными не происходит.
При этом, по логам видно, что приложение работает: оно выполняет свои бекендовые задачи, в том числе - само обращается к различным внешним сайтам и базе данных.
В логах tomcat и самого приложения ничего интересного. Вообще, с чего бы начать траблшутинг этой задачи? Это немного ново для меня.

wayerr 07.05.2017 13:21

ну спринг проглатывает некоторые ошибки, так что можно включить debugging и попытаться найти что-то в этой каше

другой путь определиться после чего оно "залипает" - попытаться воспроизвести глюк и в отладчике найти где и что

также можно снять дамп потоков и глянуть нет ли там дедлоков

Добрых дел мастер 07.05.2017 14:13

В отладчике поймать не получилось. Приложение может проработать несколько недель (обычно - дней) прежде, чем обрадует своим зависанием. Нужна какая-то зацепка, чтобы воспроизвести.

А вот про дамп потоков - интересно, почитаю.

Спасибо.

wayerr 07.05.2017 23:25

а ну тогда дамп потоков но он лишь покажет какой поток завис, если еще надо вычислить, что передали перед зависанием то вот я писал както статейку на эту тему [url]http://wayerr.livejournal.com/36753.html[/url]

Добрых дел мастер 08.05.2017 12:57

Как изящно. А я просто обернул в... по порядку:.
Чудо враждебной техники свалилось, дамп собрал.
Как и подозревал - в сосоянии blocked оказалась часть кода, вызывающая внешнюю библиотеку.
Сделал обертку в виде ExecutorService, который запускает этот вызов в отдельном потоке, ждет N секунд, прерывает вызов, делает вторую попытку, и если со второго раза за N секунд не выполнилось - значит, заяц несудьбы.
Так вот, по дампу видно, что заблокированы оба эти потока, плюс - log4j, который должен был записать в лог это событие.
Код, который должен был прибить предыдущий поток (
future.cancel(true);
executor.shutdownNow();)
очевидно выполнился, но потоки не убил.
Как такое может быть? Как можно убить эти потоки более качественно?

Добрых дел мастер 08.05.2017 13:07

кстати, внешняя библиотека (weka.core) инициализируется набором случайных чисел, и насколько я понял - в некоторых ситуациях при неудачном стечении этих случайных чисел может и не сойтись. Так что просто входящих параметров не достаточно.

wayerr 08.05.2017 13:13

>Как такое может быть? Как можно убить эти потоки более качественно?

в java нормально - никак, если клиентский код проигнорировал interruptedexception, или если там блокирующий вызов без оного - то все, теоретически возможно както нагородить костылей, но это черевато для продакшена, лучше такой код вынести в отдельный процесс (конечно не запускать его на каждый запрос, просто для того чтобы убивать когда "залип")

Добрых дел мастер 08.05.2017 13:30

ну, скорее, наверное сделать пул и следить за ним.
А как это правильнее сделать? Вот чтобы совсем по фен-шую.
Просто, опыта у меня не много, хочется приобретать сразу правильный опыт. Не хочется нагуглить какой-нибудь антипаттерн и тянуть его, пока это не приведет к факапу.

wayerr 09.05.2017 00:13

для этого надо знать все нюансы,

пул обычно делают если "болезный" процесс поддерживает только одну задачу одновременно

судя по описанию у тебя процесс использует библиотеку и поддерживает множество задач, посему если его выносить то достаточно перед ним (в используем его приложении) поставить очередь задач - лишь для того чтобы не терять их когда процесс залип и требуется его перезапустить

max 09.05.2017 12:07

Вот у опытных джавистов проблемы, а? :)
[em]"Как можно убить эти потоки более качественно?"[/em] :))
TerminateThread спасет отцов, но это не Джава. :)
Блин, как уже сказали, сними дамп да посмотри, кто залип на какой-нить RtlEnterCriticalSection или WaitForXxx.

Добрых дел мастер 09.05.2017 12:35

Там на каждый вызов создается новый экземпляр ровно одного класса, описываемого в библиотеке, скармливаются ему всякие данные и получается результат. Так что, пул здесь применим. Плюс, предварительное создание может даже ускорить процесс.

А с помощью spring integration это можно сделать?

Добрых дел мастер 09.05.2017 12:38

2Нас не забанить. Ну, посмотрел. Ну, залип. И что с этим делать дальше? Это - внешняя библиотека, править ее я не могу.
Плюс, я не говорил, что я опытный. Я только учусь.

max 09.05.2017 13:18

11-Добрых дел мастер > Ничего. Использовать другую или как-то обходить этот косяк. Неплохо было бы аффтарам черкнуть по этому поводу.

Добрых дел мастер 09.05.2017 14:37

вот я сейчас убеждаюсь, что я все правильно понял, чтобы не беспокоить аффторов без причины. И ищу способы обойти этот косяк.


Текущее время: 18:06. Часовой пояс GMT +3.