我们经常遇到与ClearDB托管的MySQL连接问题。我们有专门的计划,为我们的应用提供超过300个连接。 我知道ClearDB站点上的CBR会在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类似的经历并可能会转移到其他地方?
不幸的是,我没有任何想法,真的很感激任何帮助。答案 0 :(得分:3)
您列出的错误看起来很像您的连接已在远程端断开(即通过ClearDb)。 60s是一个非常短的空闲连接窗口,因此我建议对您的池配置进行一些更改。
1。)将initialSize和minIdle(默认为initialSize)设置为故意低。这将使空闲连接数保持较低。较少的空闲连接意味着在60秒窗口到期之前连接将被重用的可能性更大。
2。)你在这里不需要maxIdle。默认为maxActive。
3.)将timeBetweenEvictionRunsMillis设置为更低。这将设置池检查空闲连接的频率。默认值为5s可能没问题。
4.)降低minEvictableIdleTimeMillis。这是连接在被驱逐之前连接在池中的最短时间。它并不意味着它会在它老了的时候完全被驱逐。如果空闲检查刚刚运行且你的连接是minEvictableIdleTimeMillis - 1s old,它将不得不等待下一次检查以驱逐连接(即timeBetweenEvictionRunsMillis)。如果您使用默认的timeBetweenEvictionRunsMillis为5s,将其设置为50s应该会给它足够的时间。
5.)将validationInterval设置得更低。这将确定池在上次成功验证后等待多长时间再次验证连接。我会选择2到5秒之间的东西。它足够高,以至于当您忙碌时,您将获得一些好处,并且足够低,以至于它不会导致您错过关于不良连接的验证。
6。)我还建议您启用removeAbandoned和logAbandoned,将removeAbandonedTimeout设置为5或10s(大多数Web应用程序不应该长时间保持数据库连接)。这将消除您的Web应用程序将连接保持在空闲状态超过60秒,然后再次尝试使用它的可能性。