проблемы с подключением к cleardb из cloudfoundry (на пивоте)

мы постоянно сталкиваемся с проблемами с подключениями к MySQL, размещенными ClearDB. У нас есть специальный план, который предлагает более 300 подключений для нашего приложения. Я знаю, что CBR на сайте ClearDB автоматически закрывает неактивное соединение через 60 секунд.

Приложение (Spring) работает в Tomcat и использует ConnectionPool со следующими настройками:

    org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl(serviceInfo.getJdbcUrl());
    dataSource.setUsername(serviceInfo.getUserName());
    dataSource.setPassword(serviceInfo.getPassword());
    dataSource.setInitialSize(10);
    dataSource.setMaxActive(30);
    dataSource.setMaxIdle(30);
    dataSource.setTimeBetweenEvictionRunsMillis(34000);
    dataSource.setMinEvictableIdleTimeMillis(55000);
    dataSource.setTestOnBorrow(true);
    dataSource.setTestWhileIdle(true);
    dataSource.setValidationInterval(34000);
    dataSource.setValidationQuery("SELECT 1");

Ошибка, которую мы видим в нашем стеке:

 2015-01-13T13:36:22.75+0100 [App/0]   OUT The last packet successfully received from the server was 90,052 milliseconds ago.  The last packet sent successfully to the server was 90,051 milliseconds ago.; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
 2015-01-13T13:36:22.75+0100 [App/0]   OUT The last packet successfully received from the server was 90,052 milliseconds ago.  The last packet sent successfully to the server was 90,051 milliseconds ago.

 2015-01-13T13:36:22.75+0100 [App/0]   OUT  ... 52 common frames omitted
 2015-01-13T13:36:22.75+0100 [App/0]   OUT Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
 2015-01-13T13:36:22.75+0100 [App/0]   OUT  at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2914) ~[mysql-connector-java-5.1.33.jar:5.1.33]
 2015-01-13T13:36:22.75+0100 [App/0]   OUT  at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3337) ~[mysql-connector-java-5.1.33.jar:5.1.33]
 2015-01-13T13:36:22.75+0100 [App/0]   OUT  ... 64 common frames omitted

Есть ли у вас какие-либо идеи, что может быть причиной этого, или у вас был подобный опыт с ClearDB и, возможно, вы переехали куда-то еще?

к сожалению, у меня нет никаких идей, любая помощь очень ценится.


person domi    schedule 13.01.2015    source источник


Ответы (1)


Перечисленная вами ошибка очень похожа на то, что ваше соединение было разорвано на удаленном конце (например, ClearDb). 60 секунд — довольно короткое время для незанятых соединений, поэтому я предлагаю внести несколько изменений в конфигурацию вашего пула.

1.) Установите InitialSize и minIdle (по умолчанию InitialSize) преднамеренно низкими. Это снизит количество незанятых подключений. Чем меньше незанятых подключений, тем выше вероятность того, что подключение будет повторно использовано до истечения 60-секундного окна.

2.) Здесь вам не нужен maxIdle. По умолчанию это maxActive.

3.) Установите timeBetweenEvictionRunsMilli ниже. Это устанавливает, как часто пул будет проверять незанятые соединения. По умолчанию 5s, наверное, нормально.

4.) Уменьшите minEvictableIdleTimeMillis. Это минимальное количество времени, в течение которого соединение будет находиться в пуле, прежде чем его можно будет вытеснить. Это не значит, что его выселят именно тогда, когда он станет таким старым. Если только что была запущена проверка бездействия, а ваше соединение устарело minEvictableIdleTimeMillis - 1s, ему придется дождаться следующей проверки, чтобы отключить соединение (т. е. timeBetweenEvictionRunsMillis). Если вы используете timeBetweenEvictionRunsMillis по умолчанию, равное 5 с, установка этого значения на 50 с должна дать достаточно времени.

5.) Установите значение validationInterval ниже. Это определяет, как долго пул будет ждать с момента последней успешной проверки, прежде чем он снова проверит соединение. Я бы выбрал что-то между 2 и 5s. Он достаточно высок, чтобы вы могли получить некоторую выгоду, когда вы заняты, и достаточно низок, чтобы не пропустить проверку при плохом соединении.

6.) Я также предлагаю вам включить removeAbandoned и logAbandoned, а для параметра removeAbandonedTimeout установить значение примерно 5 или 10 с (большинство веб-приложений не должны удерживать соединение с базой данных так долго). Это устранит вероятность того, что ваше веб-приложение удерживает соединение в состоянии ожидания более 60 секунд, а затем пытается снова его использовать.

person Daniel Mikusa    schedule 03.02.2015
comment
Спасибо Даниэль, это очень помогло, и у меня наконец-то есть работающая конфигурация. - person domi; 07.02.2015