The last packet successfully received from the server was 8 milliseconds ago.

最近接手了一个SpringBoot+Mybatis+Mysql的JAVA爬虫项目,在爬取并解析完数据之后准备存入数据库时遇到了一个以前没有见过的报错,网上方案众多且不一定有效。记录一下自己解决这个BUG的爬坑过程。

报错信息:

org.springframework.dao.RecoverableDataAccessException: 
### Error querying database.  Cause: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet successfully received from the server was 8 milliseconds ago.  The last packet sent successfully to the server was 6 milliseconds ago.
### The error may exist in com/myc/dao/CarModelMapper.java (best guess)
### The error may involve com.myc.dao.CarModelMapper.existsWithPrimaryKey-Inline
### The error occurred while setting parameters
### SQL: SELECT CASE WHEN COUNT(car_model_id)  > 0 THEN 1 ELSE 0 END AS result  FROM car_model_all  WHERE  car_model_id = ?
### Cause: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet successfully received from the server was 8 milliseconds ago.  The last packet sent successfully to the server was 6 milliseconds ago.
; ]; Communications link failure

The last packet successfully received from the server was 8 milliseconds ago.  The last packet sent successfully to the server was 6 milliseconds ago.; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure


由于此报错只在服务器数据库出现,本地mysql并没有此问题,版本均是5.7。 尝试重启服务器端mysql以及重启服务器均无效,于是开始上网搜索解决方案.

方案1:在jdbc-url后添加 &autoReconnect=true,使用后无效,查的该方案只适用于Mysql4之前的版本有效

方案2:将mysql回收空闲连接的时间变长,mysql默认回收时间是8小时,可以在mysql目录下的my.ini中增加下面配置,将时间改为1天。单位是秒,最大好像是24天。 此配置会拖累数据库,随弃用该方案。

方案3:配置druid链接池,使用 validation-query test-on-borrow: true test-while-idle: true 三种属性,每次获取数据库连接时判断该连接是否可用。具体链接池配置参考如下表
The last packet successfully received from the server was 8 milliseconds ago._第1张图片
上表中此句描述:validationQuery 用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。所以validationQuery中的校验语句一定要正确

每种数据库都有各自的验证语句,下表中收集了几种常见数据库的validationQuery。
hsqldb          select 1 from INFORMATION_SCHEMA.SYSTEM_USERS
Oracle          select 1 from dual
DB2              select 1 from sysibm.sysdummy1
MySql           select 1
SqlServer     select1
postgresql   select version()
ingres           select 1
derby            values 1
H2                 select 1
原文:https://blog.csdn.net/qq_33101675/article/details/86504604 

使用的是mysql,所以最终链接池配置如下

  datasource:
   druid:
     url: jdbc:mysql://*****:3306/apple?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
     username: 
     password: 
     driver-class-name: com.mysql.cj.jdbc.Driver
     type: com.alibaba.druid.pool.DruidDataSource
     initial-size: 1
     max-active: 10
     min-idle: 1
     max-wait: 30000
     validation-query: select 1
     time-between-connect-error-millis: 60000
     min-evictable-idle-time-millis: 300000
     test-on-borrow: true
     test-while-idle: true
     pool-prepared-statements: true
     max-pool-prepared-statement-per-connection-size: 20

配置完成之后再次运行还是报错,开始尝试检查数据库配置,使用show global variables like '%timeout%';,检查数据库超时时间配置。
The last packet successfully received from the server was 8 milliseconds ago._第2张图片

发现数据库等待超时时间是28800s,而链接池 max-wait: 30000,所以导致项目判定该链接可用,而mysql判定该连接不可用导致连接失败。将 max-wait设置为小于28800以后,报错消失。项目运行成功。

总结:数据库配置一般不会轻易出错,所以不要轻易更改数据库配置。解决问题就从链接池配置尝试入手,使用validationQuery可能会降低性能,但数据量和使用场景对性能没有过高要求的情况下,使用此方案还是可行的

你可能感兴趣的:(BUG解决)