Spring应用程序在8小时后失去与MySql的连接.如何正确配置?

car*_*ian 22 java mysql spring hibernate connection-pooling

我有一个Spring应用程序,我相信使用DBCP连接池连接到MySql数据库.我说相信,因为这不是一个我非常强大的领域,如果一切设置正确,我不肯定.我运行应用程序没有问题,一切正常.问题一夜之间发生.该应用程序没有大量使用,一夜之间显然失去了它与MySql的连接.我调查了一下,发现MySql有一个8小时的窗口,然后断开连接或其他什么.我对此很好,但是当用户尝试在早上登录时,他们会收到如下错误:

通信链路故障.最后一个数据包成功收到60,000,000ms前.最后一个数据包在15ms前成功设置.

这就是问题.我需要它们能够在早上重新连接而不会遇到这个问题.我似乎能够解决它的唯一方法是通过弹跳Tomcat服务器.通过查看,似乎DBCP池应该能够以某种方式防止这种情况,但我找不到关于如何配置它的可靠信息来源.我希望这里有人可以为我提供一些见解.这是我当前的配置,全部在Spring xml文件中完成:

APP-data.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:annotation-config />
<context:component-scan base-package="com.vz.sts.domain" />
<context:component-scan base-package="com.vz.sts.persistence" />
<context:component-scan base-package="com.vz.sts.service" />

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="database" value="MYSQL" />
            <property name="showSql" value="true" />
        </bean>
    </property>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/app" />
    <property name="username" value="root" />
    <property name="password" value="admin" />
    <property name="initialSize" value="5" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="jdbcUserService" class="org.springframework.security.provisioning.JdbcUserDetailsManager">
    <property name="dataSource" ref="dataSource"/>
    <property name="authenticationManager" ref="authenticationManager"/>
</bean>

<bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
    <property name="userPropertyToUse" value="username" />
</bean>

<tx:annotation-driven />
</beans>
Run Code Online (Sandbox Code Playgroud)

我不确定我需要添加哪些特定属性才能允许应用程序重新连接到数据库.我不介意它是否在几个小时后关闭连接但是它应该自动重新连接并且不会抛出这样的错误.我甚至不肯定它实际设置为使用连接池.所以任何帮助都将非常感谢,谢谢.

UPDATE

我找到了这个页面,我认为我需要做的就是添加ValidationQuery属性.任何人都可以验证这是否会产生欲望影响,同时保留其他所有内容?我相信这将使用DBCP 的testOnBorrow方面.我不完全理解testOnBorrow所说的解释是什么,但我认为这会做我想要的.有谁确认?谢谢.

Ste*_*veD 4

简短的回答是应该足够了。DBCP 支持从连接池借用连接时进行测试(默认),还支持返回时测试和空闲时测试。

还值得了解这里可能出了什么问题。听起来 Tomcat 服务器和数据库之间的某些东西在超时后会断开空闲连接(例如路由器或防火墙)。这样做的问题是,Tomcat 认为它仍然具有有效的连接,尝试对该连接执行一些操作并失败,但保持连接处于活动状态并将其返回到池中。现在,如果从池中给出相同的断开连接,则任何与数据库对话的进一步尝试都将失败。

我认为这是迈克尔·尼加德(Michael Nygard)出色的“释放它!” 书中在他的一个战壕故事中描述了这一场景。

您还需要研究 MySQL 如何清理死连接,因为当 Tomcat 在 8 小时后失去连接时,数据库也不会意识到失败的连接。

最后一点,如果您使用 Tomcat 7,请切换到新的连接池,因为它提供比 DBCP 更好的性能。

  • mysql 服务器设置 `wait_timeout` 默认为 8 小时。空闲连接会在 8 小时后被删除,直到您对该连接发出查询并获得上述堆栈跟踪时,JDBC 驱动程序才会检测到这一点。(对于仅在工作时间使用的应用程序,您可以轻松获得 8 小时的空闲时间)。通常设置 DBCP testWhileIdle、validationQuery 和 timeBetweenEvictionRunsMillis 可以帮助解决此类问题,因为它会 ping 连接并使其保持活动状态。验证查询只需设置为“select 1” (2认同)
  • 经过整个周末并添加 testWhileIdle 和 timeBetweenEvictionRunsMillis 后,我可以验证这确实解决了问题。非常感谢您的回答和帮助。 (2认同)