#java #hibernate #tomcat #jdbc #java-melody
#java #спящий режим #tomcat #jdbc #java-мелодия
Вопрос:
Я целую вечность боролся с этой проблемой, и я не могу понять, в чем проблема. Позвольте мне подготовить почву для стека, который мы используем:
- Веб-приложение Java 8
- GWT
- Спящий режим 4.3.11
- MySQL
- MongoDB
- Весна
- Tomcat 8 (например, включая пул соединений Tomcat вместо C3PO)
- Поиск в режиме гибернации / Lucene
- Terracotta и EhCache
Проблема в том, что каждые пару дней (иногда каждый второй день, иногда раз в 10 дней, это меняется) рано утром наше приложение «блокируется». Чтобы уточнить, это не сбой, вы просто не можете войти в систему или что-либо сделать в этом отношении. Все фоновые задачи — все — просто останавливаются. Если мы попытаемся войти в систему, когда он находится в этом состоянии, мы увидим в нашем файле журнала, что он аутентифицирует нас как действительного пользователя, но ответ никогда не отправляется, поэтому приложение просто «вращается».
Единственная обнаруженная нами на сегодняшний день закономерность, связанная с тем, когда происходят эти «блокировки», заключается в том, что это происходит, когда выполняются наши утренние запланированные задачи или импорт SAP. Однако не всегда выполняется один и тот же процесс, иногда блокировка происходит во время одного из наших импортов SAP, а иногда и во время выполнения внутренних запланированных задач. Все, что объединяет эти вещи, это то, что они выполняются в нерабочее время (с 1 до 6 утра) и что они являются довольно интенсивными процессами.
Мы используем JavaMelody для мониторинга, и каждый раз мы видим, что, начиная с разного времени в этом окне 1-6 утра, количество используемых соединений jdbc только начинает расти (согласно прикрепленному изображению). Как только это начнется, это всего лишь вопрос времени, прежде чем произойдет блокировка, и единственный способ решить ее — отказать Tomcat, тем самым перезапустив приложение.
Что касается, насколько я могу судить, Память, процессор и т. Д. Все в порядке, Когда происходит блокировка, Единственное, что выглядит так, как будто у него есть проблема, — это постоянно растущее число используемых соединений jdbc.
Я так много раз проверял код для нашего управления транзакциями, чтобы убедиться, что транзакции закрываются правильно (код управления транзакциями довольно старомоден: явное начало и фиксация в блоке try, откат в блоках catch и закрытие entity manager в блоке finally). Мне все кажется правильным, поэтому я действительно, действительно в тупике. В дополнение к этому я также недавно явно настроил режим освобождения соединения в режиме гибернации на after_transaction, но проблема все еще возникает.
Другая странная вещь заключается в том, что мы запускаем несколько экземпляров одного и того же приложения для разных клиентов, и эта проблема возникает регулярно только для одного клиента. Они являются нашим клиентом с наибольшим количеством обрабатываемых данных, и хотя все клиенты выполняют эти запланированные задачи, этот большой клиент является единственным с импортом SAP. Вот почему я изначально думал, что проблема заключалась в импорте SAP, но он заблокировался сразу после 1 часа ночи этим утром, и это было за пару часов до того, как импорт даже начал выполняться. В этом случае он заблокирован во время выполнения внутренней запланированной задачи.
У кого-нибудь есть идеи, что может быть причиной такого странного поведения? Я изучил все, что мог придумать, но безрезультатно.
Комментарии:
1. Вы говорите, что транзакции закрываются, но закрываете ли вы менеджеров сущностей? Вам также необходимо закрыть их, чтобы освободить соединение обратно в пул.
2. @coladict Я не думаю, что это правда, потому что, как я уже упоминал, я установил режим освобождения соединения после транзакции, поэтому он должен освободить их при фиксации / откате, насколько я понимаю из документов. В любом случае, это спорный вопрос, поскольку в своем вопросе я сказал, что я закрываю диспетчер сущностей в блоке finally.
3. Что ж, в разделе «Информация о системе» на странице мониторинга есть ссылка «Открытые соединения jdbc», которая поможет вам найти любые утечки. Если есть какие-либо открытые соединения, вы получите трассировку стека, из которой было создано соединение, пик которого, вероятно, будет где-то в спящем режиме, но вам просто нужно спуститься, пока не дойдете до своих классов.
4. @coladict Я не вижу истории этой информации. Когда приложение заблокировано, я не могу получить доступ / мониторинг, и как только я отскочил от него, данные «в реальном времени» исчезли, и я могу получить доступ только к историческим данным, показанным на графиках. Ну, по крайней мере, насколько я знаю, если вы не знаете, как я могу получить данные, на которые вы ссылаетесь, после того, как я отскочил от приложения / кота.
5. попробуйте получить дамп потока с помощью jconsole или visualvm или любых других командных инструментов, таких как jmap или jstack. Затем проанализируйте дамп потока с помощью анализатора стека потоков (вы также можете сделать это с помощью текстового редактора) и посмотрите, кто удерживает соединения.
Ответ №1:
После некоторого времени и множества проб и ошибок нам с моей командой удалось решить эту проблему. Оказывается, что всплеск подключений JDBC не был причиной блокировок, а был следствием блокировок. Виновником был Apache Terracotta. Похоже, он просто перестал отвечать на запросы. Возможно, это была проблема с распределением ресурсов, но я так не думаю, поскольку это происходило на серверах, которые также использовались с низким уровнем использования, и у них было более чем достаточно доступных ресурсов.
К счастью, нам больше не нужна была Terracotta, поэтому я удалил ее. Как я уже говорил в вопросе, мы получали эти блокировки каждые пару дней — по крайней мере, раз в неделю, каждую неделю. С момента его удаления у нас не было таких блокировок в течение 4 месяцев и подсчета. Поэтому, если у кого-то еще возникнет такая же проблема, и вы используете Terracotta, попробуйте удалить ее, и все может наладиться, как это было в моем случае.
Ответ №2:
Как сказал coladict, вам нужно посмотреть страницу «Открытые соединения jdbc» в отчете о мониторинге javamelody и до того, как сервер «заблокируется».
Извините, если вам нужно сделать это в 2 часа или 3 часа утра, но, возможно, вы можете автоматически запускать команду wget ночью.