Попытка определить источник заброшенных соединений в Tomcat - PullRequest
9 голосов
/ 18 апреля 2011

Я использую пул соединений dbcp в Tomcat (версия 7), и у меня есть утечка соединения где-то в моем коде.Через короткое время запрос на новое соединение возвращает следующее исключение:

"Не удается получить соединение, ошибка пула Тайм-аут ожидания незанятого объекта"

Я вернулся через свой коди мне кажется, что все соединения закрываются должным образом (не все так говорят ...).

Чтобы отладить это, я добавил следующие свойства в context.xml:

logAbandoned="true" removeAbandoned="true" removeAbandonedTimeout="300"

Итак, тег ресурса теперь выглядит следующим образом:

 <Resource name="jdbc/findata" auth="Container" type="javax.sql.DataSource"
               maxActive="20" maxIdle="5" maxWait="10000"
               username="root" password="xxxxxx" driverClassName="com.mysql.jdbc.Driver"
               logAbandoned="true" removeAbandoned="true" removeAbandonedTimeout="300"
               url="jdbc:mysql://localhost:3306/findata"/>

Затем я перезапустил tomcat и начал посещать веб-страницы, пока не появилось сообщение об ошибке (в окне браузера).Однако я еще не смог выяснить, где свойство logAbandoned записывает свою информацию.Я смотрю в

/usr/share/apache-tomcat-7.0.11/logs

, но единственный недавно измененный файл журнала там

localhost_access_log.2011-04-18.txt

Любая помощь очень ценится.

Ответы [ 3 ]

7 голосов
/ 20 сентября 2013

Согласно этому сайту вы должны предоставить фабрику для вашего определения ресурса из вашего context.xml. Конфигурация ресурса будет выполняться этим экземпляром фабрики, поэтому все «дополнительные» параметры устанавливаются таким образом. Чтобы быть более конкретным, вы должны иметь что-то подобное в вашем context.xml (или server.xml - зависит от того, где вы определяете свой ресурс):

<Resource name="jdbc/db" auth="Container" type="javax.sql.DataSource"
 factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
 driverClassName="org.postgresql.Driver" url="jdbc:postgresql://127.0.0.1/db"
 username="hibernate" password="hibernate" maxActive="20" maxIdle="10"
 maxWait="1000" removeAbandoned="true" removeAbandonedTimeout="20"
 logAbandoned="true" />  

Обратите внимание на factory="org.apache.tomcat.jdbc.pool.DataSourceFactory", который необходим для нашей цели. Без этого removeAbandoned="true" не имеет никакого эффекта.

Стеки каждого оставленного соединения хранятся в catalina.log ($tomcat_dir/logs). Оттуда это даст довольно точные детали для отладки соединений.

Помимо «заброшенных» параметров, вы можете настроить множество вещей, связанных с производительностью пула tomcat jdbc, таймаутами и другими оттенками и болтами. Конечно, это требует глубоких знаний. (Подробности можно найти на сайте, который я изначально предоставил)

4 голосов
/ 18 апреля 2011

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

3 голосов
/ 18 апреля 2011

Один из относительно простых способов убедиться, что вы всегда закрываете соединение, - это вставить его в фильтр сервлета, поместить его в ThreadLocal, использовать этот ThreadLocal через весь ваш код, а затем закрыть его, когда ответ пройдет через фильтр. (Оптимизация заключалась бы в размещении прокси-сервера в ThreadLocal, который получает соединение только по первому запросу).

Но ваша непосредственная проблема - найти источник утечки, верно?

Во-первых, убедитесь, что вы закрыли соединения в инструкции finally {}, чтобы исключение не помешало вам сделать это.

Во-вторых, неясно, сколько времени понадобится logAbandoned, чтобы выяснить, простаивает ли соединение. Попробуйте подождать некоторое время, может быть 15 минут или около того.

В-третьих, вы можете использовать прокси-драйверы JDBC, такие как http://code.google.com/p/log4jdbc/. Они генерируют журнал всех действий над подключениями, поэтому вы можете найти в журнале несоответствие open () и close ().

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...