Тайм-аут соединения с MySQL - приложение Grails на Tomcat с использованием Hibernate и ORM - PullRequest
20 голосов
/ 30 апреля 2010

У меня есть небольшое приложение Grails, работающее на Tomcat в Ubuntu на VPS. Я использую MySql в качестве хранилища данных, и все работает нормально, если я не покидаю приложение более чем на полдня (8 часов?). Я провел некоторый поиск, и, очевидно, это значение по умолчанию wait_timeout в mysql.cnf, поэтому через 8 часов соединение прекратит свое существование, но Tomcat не узнает, поэтому, когда следующий пользователь попытается просмотреть сайт, он увидит ошибку сбоя соединения. Обновление страницы исправит это, но я хочу полностью избавиться от ошибки. Для моей версии MySql (5.0.75) у меня есть только my.cnf, и он не содержит такого параметра. В любом случае изменение этого параметра не решит проблему.

Это Сообщение в блоге , кажется, сообщает о подобной ошибке, но я все еще не до конца понимаю, что мне нужно настроить, чтобы исправить это, и я также надеюсь, что есть более простое решение, чем другая треть тусовочная библиотека. Машина, на которой я работаю, имеет оперативную память 256 МБ, и я стараюсь, чтобы количество запущенных программ / служб было минимальным.

Что-то, что я могу настроить в Grails / Tomcat / MySql, чтобы это исчезло?

Заранее спасибо,

Гав

Из моей Каталины.out;

2010-04-29 21:26:25,946 [http-8080-2] ERROR util.JDBCExceptionReporter  - The last packet successfully received from the server was 102,906,722 milliseconds$
2010-04-29 21:26:25,994 [http-8080-2] ERROR errors.GrailsExceptionResolver  - Broken pipe
java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method)
         ...
2010-04-29 21:26:26,016 [http-8080-2] ERROR util.JDBCExceptionReporter  - Already closed.
2010-04-29 21:26:26,016 [http-8080-2] ERROR util.JDBCExceptionReporter  - Already closed.
2010-04-29 21:26:26,017 [http-8080-2] ERROR servlet.GrailsDispatcherServlet  - HandlerInterceptor.afterCompletion threw exception
org.hibernate.exception.GenericJDBCException: Cannot release connection
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.SQLException: Already closed.
        at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:84)
        at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.close(PoolingDataSource.java:181)
        ... 1 more

Ответы [ 7 ]

18 голосов
/ 03 мая 2010

Ссылаясь на эту статью , в вашем пуле подключений DBCP есть устаревшие соединения, которые незаметно сбрасываются ОС или брандмауэром.

Решение состоит в том, чтобы определить запрос проверки и выполнить проверку работоспособности соединения, прежде чем вы фактически используете его в своем приложении. В Grails это фактически делается путем изменения файла grails-app / conf / spring / Resource.groovy и добавления следующего:

beans = {
  dataSource(BasicDataSource) {
    //run the evictor every 30 minutes and evict any connections older than 30 minutes.
    minEvictableIdleTimeMillis=1800000
    timeBetweenEvictionRunsMillis=1800000
    numTestsPerEvictionRun=3
    //test the connection while its idle, before borrow and return it
    testOnBorrow=true
    testWhileIdle=true
    testOnReturn=true
    validationQuery="SELECT 1"
  }
} 
5 голосов
/ 20 февраля 2011

В grails 1.3.X вы можете изменить значения evictor в файле DataSource.groovy, чтобы убедиться, что пулы соединений используются во время простоя. Это гарантирует, что сервер MySQL не будет превышать время ожидания соединения.

production {
  dataSource {
    pooled = true
    // Other database parameters..
    properties {
       maxActive = 50
       maxIdle = 25
       minIdle = 5
       initialSize = 5
       minEvictableIdleTimeMillis = 1800000
       timeBetweenEvictionRunsMillis = 1800000
       maxWait = 10000
    }
}

Быстрый способ убедиться в этом - изменить элемент конфигурации MySQL my.cnf [mysql] и добавить параметр wait_time с низким значением.

1 голос
/ 31 марта 2016

Добавьте эти параметры в источник данных

        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = true

См. Эту статью для получения дополнительной информации http://sacharya.com/grails-dbcp-stale-connections/

1 голос
/ 15 февраля 2011

Для grails 1.3.X мне пришлось добавить следующий код в Bootstrap.groovy:

  def init = {servletContext ->
  def ctx=servletContext.getAttribute(ApplicationAttributes.APPLICATION_CONTEXT)

    //implement test on borrow
    def dataSource = ctx.dataSource
    dataSource.targetDataSource.setMinEvictableIdleTimeMillis(1000 * 60 * 30)
    dataSource.targetDataSource.setTimeBetweenEvictionRunsMillis(1000 * 60 * 30)
    dataSource.targetDataSource.setNumTestsPerEvictionRun(3)
    dataSource.targetDataSource.setTestOnBorrow(true)
    dataSource.targetDataSource.setTestWhileIdle(true)
    dataSource.targetDataSource.setTestOnReturn(false)
    dataSource.targetDataSource.setValidationQuery("SELECT 1")

  }

Мне также пришлось импортировать org.codehaus.groovy.grails.commons.ApplicationAttributes

1 голос
/ 30 апреля 2010

Попробуйте увеличить количество открытых подключений MySQL, указав в DataSources.groovy следующее:

dataSource {
     driverClassName = "com.mysql.jdbc.Driver"
     pooled=true
     maxActive=10
     initialSize=5
     // Remaining connection params
}

Если вы хотите использовать всю нагрузку, попробуйте реализовать пул соединений; Вот полезная ссылка на этом.

0 голосов
/ 01 октября 2015

Начиная с grails 2.3.6 в конфигурации по умолчанию уже есть опции для предотвращения закрытия соединения по таймауту

Это новые значения по умолчанию.

    properties {
       // See http://grails.org/doc/latest/guide/conf.html#dataSource for documentation
       ....
       minIdle = 5
       maxIdle = 25
       maxWait = 10000
       maxAge = 10 * 60000
       timeBetweenEvictionRunsMillis = 5000
       minEvictableIdleTimeMillis = 60000
       validationQuery = "SELECT 1"
       validationQueryTimeout = 3
       validationInterval = 15000
       testOnBorrow = true
       testWhileIdle = true
       testOnReturn = false
       jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
       defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
    }
0 голосов
/ 30 апреля 2010

Как выглядит ваша строка подключения JDBC? Вы можете установить параметр autoReconneect в конфигурации источника данных, например,

jdbc:mysql://hostname/mydb?autoReconnect=true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...