如何检查 Spring Boot 使用了啥数据库池?

Posted

技术标签:

【中文标题】如何检查 Spring Boot 使用了啥数据库池?【英文标题】:How to check what database pool is used with Spring Boot?如何检查 Spring Boot 使用了什么数据库池? 【发布时间】:2016-04-09 13:41:58 【问题描述】:

我正在使用带有 mysql 的 Spring Boot 1.3.1。我在我的日志中得到了这个:

The last packet successfully received from the server was 97,025,381 milliseconds ago.  
The last packet sent successfully to the server was 97,025,381 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.

全栈:

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 97,025,381 milliseconds ago.  The last packet sent successfully to the server was 97,025,381 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) ~[na:1.8.0_66]
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_66]
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_66]
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_66]
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:981) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3652) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2460) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2625) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2547) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
        at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:4874) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]
        at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[na:na]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_66]
        at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_66]
        at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) ~[tomcat-jdbc-8.0.30.jar!/:na]
        at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) ~[tomcat-jdbc-8.0.30.jar!/:na]
        at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81) ~[tomcat-jdbc-8.0.30.jar!/:na]
        at com.sun.proxy.$Proxy78.setAutoCommit(Unknown Source) ~[na:na]
        at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:72) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1471) ~[hibernate-core-4.3.11.Final.jar!/:4.3.11.Final]
        at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:61) ~[hibernate-entitymanager-4.3.11.Final.jar!/:4.3.11.Final]
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:170) ~[spring-orm-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
        at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380) ~[spring-orm-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373) ~[spring-tx-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:427) ~[spring-tx-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:276) ~[spring-tx-4.2.4.RELEASE.jar!/:4.2.4.RELEASE]
        ... 80 common frames omitted
Caused by: java.net.SocketException: Broken pipe
        at java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:1.8.0_66]
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109) ~[na:1.8.0_66]
        at java.net.SocketOutputStream.write(SocketOutputStream.java:153) ~[na:1.8.0_66]
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[na:1.8.0_66]
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[na:1.8.0_66]
        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3634) ~[mysql-connector-java-5.1.38.jar!/:5.1.38]

根据spring boot docs,tomcat-pool 通常应该自动使用,因为我依赖于 JPA 启动器:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

有没有办法检查这个?

/beans 端点返回一个像这样的 bean:


"bean": "dataSource",
"scope": "singleton",
"type": "org.apache.tomcat.jdbc.pool.DataSource",
"resource": "class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]",
"dependencies": []

所以我认为它正在使用tomcat池。

这个question 谈论spring.datasource.test-while-idlespring.datasource.validation-interval。是否需要设置它们以避免出现问题?

【问题讨论】:

我不确定您的问题标题与实际问题之间的关系。所以,是的,它正在使用您发现的 Tomcat 连接池。 好的,抱歉标题不好。但为什么我会得到例外?我是否需要使用最后两个属性来避免它?任何指向解释这些的文档的链接? 它写在那里,在您发布的堆栈跟踪中:at org.apache.tomcat.jdbc.pool 【参考方案1】:

spring-boot-starter-jdbc(也被 jpa-data 引用)依赖于 Tomcat 池,因此默认情况下您使用的是 Tomcat 池。您可以通过检查您的 Maven 依赖项列表轻松验证这一点。 (您发布的堆栈跟踪也证实了这一点)

这意味着你应该使用tomcat-pooling parameters:

testWhileIdle 验证间隔 验证查询

【讨论】:

谢谢。刚刚发现了这个很好的答案,它更详细地解释了这些属性:***.com/questions/30451470/…

以上是关于如何检查 Spring Boot 使用了啥数据库池?的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Boot:如何设置 JDBC 池属性,例如最大连接数?

Spring Boot : ORM 框架 JPA 与连接池 Hikari

如何使用 Spring Boot 设置 Spring JDBC 连接池?

如果我们重新启动 Spring Boot 应用程序,正在运行的用户线程发生了啥?

Spring Boot 整合 Druid

如何使用 Hibernate 和 Spring Boot 配置和监控 HikariCP