问题症状

在Win7和Win10下启动时均会出现下面的错误,但是在OSX和Linux下没问题

  1. com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
  2. The last packet successfully received from the server was 18,982 milliseconds ago. The last packet sent successfully to the server was 18,979 milliseconds ago.
  3. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  4. at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  5. at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  6. at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
  7. at com.mysql.jdbc.Util.handleNewInstance(Util.java:403)
  8. at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)
  9. ...
  10. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  11. at java.lang.reflect.Method.invoke(Method.java:498)
  12. at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
  13. Caused by: java.net.SocketException: Connection reset
  14. at java.net.SocketInputStream.read(SocketInputStream.java:210)
  15. at java.net.SocketInputStream.read(SocketInputStream.java:141)
  16. at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:101)
  17. at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:144)
  18. at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:174)
  19. at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2966)
  20. at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3427)
  21. ... 166 common frames omitted

配置文件

  1. spring:
  2. datasource:
  3. type: com.alibaba.druid.pool.DruidDataSource
  4. druid:
  5. aservice:
  6. driverClassName: com.mysql.jdbc.Driver
  7. url: jdbc:mysql://192.168.1.2:3306/aservice?useUnicode=true&characterEncoding=utf8
  8. username: dbuser
  9. password: dbuser
  10. bservice:
  11. ...
  12. ...
  13. validationQuery: SELECT 1 FROM DUAL
  14. testWhileIdle: true

对应的各组件版本为

spring-boot-dependencies:2.1.17.RELEASE

druid-spring-boot-starter:1.1.17

mysql-connector-java:auto --> 8.0.21

检查过程

排除网络及MySQL服务器账号问题:用客户端可以正常连接,同样的代码在OSX和Ubuntu20.04下均可正常连接。如果通过公网opnvpn连接到内网,在windows下也可以正常连接

排除mysql-connector-java版本不兼容问题:切换到8.0.16和5.1.46后问题依旧

排除mysql-connector-java自身问题:仅使用spring-jdbc + mysql-connector-java 可以正常连接

在SpringBoot:2.2.4.RELEASE + hikari的项目B上,在同样的内网环境连接此数据库,无法连接。因此问题范围可以缩小到SpringBoot上。

这个项目里出现的错误不太一样,是

  1. 201030 14:09:11275 main W xxer.hikari.pool.PoolBase#481 HikariPool-1 - Default transaction isolation level detection failed (No operations allowed after connection closed.).
  2. 201030 14:09:11279 main E er.hikari.pool.HikariPool#493 HikariPool-1 - Error thrown while acquiring connection from data source
  3. java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed.
  4. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
  5. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
  6. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
  7. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
  8. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
  9. at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:73)
  10. at com.mysql.cj.jdbc.ConnectionImpl.setTransactionIsolation(ConnectionImpl.java:2279)
  11. ...
  12. at com.rockbb.banyan.commons.impl.CommonsBoot.main(CommonsBoot.java:14)
  13. Caused by: com.mysql.cj.exceptions.ConnectionIsClosedException: No operations allowed after connection closed.
  14. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
  15. at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
  16. at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
  17. at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
  18. at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
  19. at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
  20. at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
  21. at com.mysql.cj.NativeSession.checkClosed(NativeSession.java:1274)
  22. at com.mysql.cj.jdbc.ConnectionImpl.checkClosed(ConnectionImpl.java:575)
  23. at com.mysql.cj.jdbc.ConnectionImpl.setTransactionIsolation(ConnectionImpl.java:2226)
  24. ... 70 common frames omitted

在项目B上,通过debug发现连接关闭这个状态是通过NativeSession.forceClose()设置的,调用栈是

com.mysql.cj.jdbc.ConnectionImpl.abortINternal()

com.mysql.cj.jdbc.ConnectionImpl.isValid()

com.zaxxer.hikari.pool.PoolBase.checkValidationSupport()

在这个方法里,判断连接是否有效有两种方法,

  1. if (this.isUseJdbc4Validation) {
  2. connection.isValid(1);
  3. } else {
  4. this.executeSql(connection, this.config.getConnectionTestQuery(), false);
  5. }

出错时使用的是前一种,这里timeout是固定的1秒,在这1秒内无返回就出错了。因为超时不能修改,所以要改用第二种,可以看到这个对象初始化时这个变量的赋值为

  1. this.isUseJdbc4Validation = config.getConnectionTestQuery() == null;

所以只需要配置中有connection-test-query: "SELECT 1"这一项就可以了,在hikari的配置中加上这项,程序就可以正常运行了。

回到项目A,项目A使用的是DruidDatasource, 没有上面的这个参数项,配置这个不起作用。

对项目中出现异常的部分加断点debug,可以发现异常的来源是com.mysql.cj.protocol.ReadAheadInputStream.fill(), 实际的错误来源是socket read timeout,这个类里有一个doDebug变量可以控制是否输出socket读写的信息,再继续跟踪得到这个选项是traceProtocol=true, 要配置到dbUrl上。

打开这个信息后发现,实际上连接出错是在和服务器多次交互后才发生的。

继续跟踪,连接的关闭是在这个方法后发生的com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker.isValidConnection(...),这个方法里通过ping和sql查询两种方式检查连接有效性,并且查询的timeout也是1秒,所以先修改timeout试试,在druid的配置上加上

  1. validationQueryTimeout: 30

后,debug中可以发现确实ping阻塞在那里直到超时也无返回,所以这个不能解决问题,再尝试换成另一种方式检查有效性。这个开关字段是usePingMethod,经过检查,这个参数不能通过application.yml带入,要加在java启动时的命令行,加上-Ddruid.mysql.usePingMethod=false这个参数启动后,就会通过SELECT 1去检查连接有效性,这个检测就没问题。因为超时时间也使用于这个检测,所以最终解决方案是

  • 启动命令行中加上 -Ddruid.mysql.usePingMethod=false 参数
  • application.yml的Druid配置中加上 validationQueryTimeout: 30 和 validationQuery: SELECT 1这两项

Windows下,SpringBoot JDBC无法连接的问题的更多相关文章

  1. Windows下用C语言连接Mysql注意问题

    原文:Windows下用C语言连接Mysql注意问题 环境是:在VS6.0 安装Mysql后,我们需要相应的头文件以及lib文件,所以安装过程必须是完整安装.否则不会生成include文件夹哦~ 具体 ...

  2. 转 windows下安装pycharm并连接Linux的python环境 以及 windows 下notepad ++编辑 linux 的文件

    ######sample 1:windows下安装pycharm并连接Linux的python环境 https://www.cnblogs.com/junxun/p/8287998.html wind ...

  3. windows下使用xShell远程连接virtualbox里面的linux

    第一阶段:基本安装 安装virtual box 在virtualbox里面安装xubuntu:是ubuntu+xfce桌面环境的一个linux的发行版本 在windows下安装Xmanager Ent ...

  4. [linux RedHat]windows下使用putty远程连接linux 下载JDK和tomcat

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/43154543 本文作者:sushengmiyan ------------------ ...

  5. windows下安装pycharm并连接Linux的python环境

    1. 下载安装Pycharm专业版 具体方法略.Pycharm5激活方法参考http://www.cnblogs.com/snsdzjlz320/p/7110186.html 2. 添加配置连接远程服 ...

  6. 3.Ubuntu下安装mysql并在windows下使用Navicat来连接

    一.安装mysql(只需要三条命令) 1.第一条命令(中间需要输入root用户密码): sudo apt-get install mysql-server 2.第二条命令: sudo apt-get ...

  7. [转载+补充][PY3]——环境配置(2)——windows下安装pycharm并连接Linux的python环境

    原文地址:<你所会用到的Python学习环境和工具> 1. 下载安装Pycharm专业版 具体方法略.Pycharm5激活方法参考http://www.cnblogs.com/snsdzj ...

  8. 在 windows 下搭建 IDEA + Spark 连接 Hive 的环境

    为了开发测试方便,想直接在 IDEA 里运行 Spark 程序,可以连接 Hive,需不是打好包后,放到集群上去运行.主要配置工作如下: 1. 把集群环境中的 hive-core.xml, hdfs- ...

  9. Windows下通过SSH无密码连接Linux服务器

    一.配置环境 1.本机系统:Windows 10 Pro(64位) 2.服务器:CentOS 6.10(64位) 3.SSH连接软件:SecureCRT 二.配置SSH无密码登录步骤 1.在个人PC机 ...

  10. Windows下使用console线连接思科交换机

    在XP下可以直接使用内置工具"超级终端",在win7或者更高版本需要下载安装SecureCRT. 本文假设已经下载安装好了SecureCRT. 首先,将电脑连接console线.因 ...

随机推荐

  1. DFT Architecture

    Design For Test 在实际生产过程中产生的physical defect是导致芯片功能出错的根本原因 如何根据结构产生测试向量呢?主要考虑physical defect physical ...

  2. [转帖]浏览器HTTP请求并发数和TCP连接的关系

    https://cloud.tencent.com/developer/article/1518678 面试题目(头条): 网页中的图片资源为什么分放在不同的域名下? 浏览器与服务器建立一个TCP连接 ...

  3. [转帖]MYSQL--表分区、查看分区

    https://www.cnblogs.com/pejsidney/p/10074980.html 一.       mysql分区简介 数据库分区 数据库分区是一种物理数据库设计技术.虽然分区技术可 ...

  4. [转帖]tidb集群部署

    http://blog.itpub.net/29785807/viewspace-2789852/ 一.安装规划 1 2 3 4 5 6 使用15台服务器 5台tidb服务器:每台3个tidb实例+1 ...

  5. [转帖]5.2. 使用HINT

    ¶ 本章节包含以下内容: 概述 HINT的功能 HINT的使用 配置参数 示例 注意 5.2.1. 概述 ¶ KingbaseES使用的是基于成本的优化器.优化器会估计SQL语句的每个可能的执行计划的 ...

  6. [转帖]Elasticsearch 的 30 个调优最佳实践!

    Elasticsearch 的 30 个调优最佳实践! https://zhuanlan.zhihu.com/p/406264041 ES 发布时带有的默认值,可为 es 的开箱即用带来很好的体验.全 ...

  7. Springboot 数据库连接池大小简单总结

    最近在进行性能压测, 想验证一下产品的极限性能, 在使用openpower 2路22核(SMT4)176线程 512G内存的服务器上面进行性能压测 压测进行到1000并发或者是2000并发时性能有一定 ...

  8. ARC150D - Removing Gacha (树上期望)

    Link 题意: 给一棵 \(n\) 个节点的树,称一个点是好的,当且仅当它到根的路径上都是黑色(包括自己).每次在不好的节点中随机选一个把它涂成黑色(不管原来它是否是白的),直到所有点都是好的为止. ...

  9. vue3关于.sync的用法

    场景描述 我们都知道,子组件是不能够去修改父组件传递过来的数据. 因为如果子组件去修改父组件件传递过来的数据. 会导致数据的应用流向变得难以理解. 但是有些时候,我们需要当子组件的数据变化后,父组件的 ...

  10. git查看自己是从那个分支建的分支

    可能发生的情况 很多时候,开始建分支的时候, 能够确认自己是那个分支建的,但是当写完功能之后, 再去回想,有时是忘记自己基于那个分支建的分支. 这时有一个命令的话就可以很快的定位了. 查看创建的分支来 ...