Конфигурация Tomcat с использованием DBCP

Мы получаем исключение CommunicationsException (от DBCP) через некоторое время (несколько часов). Сообщение об ошибке (в исключении) находится в конце этого вопроса, но я не вижу, чтобы wait_timeout был определен ни в одном из файлов конфигурации. (Где искать? Где-нибудь из каталога tomcat / conf?).

Во-вторых, как предполагает исключение, где поместить свойство «Connector / J connection 'autoReconnect = true'»? Вот определение ресурса в файле conf / context.xml в настройке tomcat:

<Resource name="jdbc/TomcatResourceName" auth="Container" type="javax.sql.DataSource"
           maxActive="100" maxIdle="30" maxWait="10000"
           removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
           username="xxxx" password="yyyy"
           driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://127.0.0.1:3306/dbname?autoReconnect=true"/>

В-третьих, почему JVM ожидает вызова executeQuery (), чтобы выбросить исключение? Если время соединения истекло, метод getConnection должен выдать исключение, не так ли? Я говорю об этом разделе исходного кода:

        try {
                conn = getConnection (true);
                stmt = conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
                                                ResultSet.CONCUR_READ_ONLY);
                rset = stmt.executeQuery (bQuery);
                while (rset.next()) {
                     ....

Наконец, вот несколько первых строк трассировки стека ...

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 84,160,724 milliseconds ago.  The last packet sent successfully to the server was 84,160,848 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3291)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1938)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2107)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2642)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2571)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1451)
at org.apache.tomcat.dbcp.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)

Это причины, по которым некоторые из нас думают: «забудьте о dbcp, он может настолько зависеть от конфигураций IDE и скрытой магии, что DriverManager.getConnection (...) может быть более надежным». Есть комментарии по этому поводу? Спасибо за понимание, - М.С.


person Manidip Sengupta    schedule 09.02.2011    source источник


Ответы (2)


Поскольку DBCP сохраняет открытые возвращенные соединения mysql для предстоящих запросов на соединение, они становятся жертвами Тайм-аут сервера MySQL.

DBCP имеет ряд функций, которые могут помочь (может использоваться, начиная с Tomcat 5.5 IIRC).

validationQuery="SELECT 1"
testOnBorrow="true"

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

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

Другие возможные подходы:

  1. используйте testWhileIdle="true" DBCP в настройках ресурсов, чтобы также проверять незанятые соединения, прежде чем будет обнаружен эффективный запрос.

  2. Используйте 'connectionProperties', чтобы укрепить соединение с MySQL (например, autoReconnect/autoReconnectForPools=true)

person Alain Pannetier    schedule 09.02.2011
comment
Если я вас правильно понимаю, DBCP сохраняет свое соединение в своем пуле, но сервер mySql отключает его, поэтому, когда это соединение отправляется в приложение, это закрытое соединение. Имеет смысл, но правильно ли я это понимаю? Другой вопрос: есть ли смысл использовать validationQuery / testOnBorrow, как вы упомянули, а также testWhileIdle и autoRecon ... в файле context.xml? Они входят в этот файл, верно? - person Manidip Sengupta; 10.02.2011
comment
1. Ваше понимание правильное. Все указанные мной решения дополняют друг друга. Настройка одного не мешает настроить другие. Ремень и подтяжки лучше ;-) Я бы реализовал все 3 решения. Тестирование в режиме ожидания означает меньшее время ожидания при «заимствовании». Настройки свойств уменьшат количество несвоевременных отключений. Да, все они входят в ресурсную часть вашего webapp context.xml (позже развернутую tomcat в $ CATALINA_HOME / conf / Catalina / localhost / yourwebapp.xml). - person Alain Pannetier; 10.02.2011
comment
autoReconnect не рекомендуется - dev.mysql .com / doc / refman / 5.0 / en / - person OrangeDog; 10.02.2011

DBCP не предназначен для использования в производственной среде, даже авторы говорят об этом (см. Эту презентацию: http://www.infoq.com/presentations/Tuning-Tomcat-Mark-Thomas).

Предлагаю взглянуть на C3P0: http://www.mchange.com/projects/c3p0/index.html

person Spajus    schedule 09.02.2011
comment
Это не правда. Есть темы о вашем сравнении, и разница не очевидна или неочевидна. stackoverflow.com/ questions / 520585 / и stackoverflow.com/questions/490288/ - person Alfabravo; 10.02.2011
comment
В этой презентации рассказывается о том, когда использовать BIO и NIO, в зависимости от продолжительности сеанса и требований параллелизма (у нас мало ответов по обоим вопросам). Любой указатель на то, почему его не следует использовать в производстве? Просто соображения о высокой частоте подключения? Кстати, я взглянул на C3P0, выглядит очень интересно, мы могли бы попробовать, если DBCP продолжает доставлять нам проблемы. Спасибо за информацию, - ср. - person Manidip Sengupta; 10.02.2011
comment
Если я правильно помню, в этой презентации есть момент, когда этот парень говорит, что DBCP никогда не предназначалась для использования в производстве или в чем-то в этом роде. Да, это иголка в стоге сена, но я не мог забыть об этом после того, как услышал это. - person Spajus; 10.02.2011
comment
C3P0 не поддерживает функции JDBC4. Источник: sourceforge.net/tracker/ - person fdaugan; 08.01.2013