概述
由于系统长时间没人用,达到了默认的最大空闲时间的间隔,导致连接被回收。而在再次进行数据库调用的时候会去获取连接,从而导致首次调用系统较慢。
需要引入keepAlive机制(添加两配置参数)去解决这个问题。
下面是分析过程的详细描述。
问题
系统用的人数比较少,有两个模块隔一段时间不调用,然后在进行调用就比较慢。大概需要10秒的时间。然后调用一次之后,后续的调用就又比较快了。
首先怀疑就是缓存问题,在运行一次就有缓存了。导致后续运行比较快。
经代码分析,无缓存,代码就是很简单的数据库查询,而且不存在慢sql。
这个时候就有了新的怀疑方向,数据库连接池的连接没了,是不是在新建连接。
现场
配置
spring:
datasource:
url: xxx
username: xxx
password: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 10
max-wait: 10000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 3600000
test-while-idle: true
validation-query: SELECT 1
test-on-borrow: false
test-on-return: false
jar包版本
spring:5.3.19
druid:<druid.version>1.2.9</druid.version>
服务器连接观测
命令: netstat -antp
启动时的连接
很长时间不访问的连接
访问一次之后的连接
这个时候有了怀疑方向,我的连接哪里去了,为什么我配置了min-idle,却没有保存5个连接。
连接消失分析过程
观测
查看数据库连接断开的时间是两个小时还是7个小时
当前9:50新建的连接
11:09连接还在
13:33连接还在
17:00 连接消失
观测下来是7个小时连接自动消息,且没有重新创建
配置学习
总结
当前配置解读
我之前一直以为这个会有心跳,让连接保持存活
min-evictable-idle-time-millis: 3600000
test-while-idle: true
validation-query: SELECT 1
当前配置,首先只有在获取的时候满足 空闲时间 大于min-evictable-idle-time-millis 的时候才会进行调用'SELECT 1' 检查连接是否正常,异常的话,移除连接并且发送缺少连接的信号,让创建线程创建连接。
让连接失效的原因
空闲时间大于maxEvictableIdleTimeMillis(默认7个小时),则会进行连接强制回收
加入keepalive机制
这个机制是在timeBetweenEvictionRunsMillis的时间间隔情况下执行。
keepAlive的引入会让其定时(keepAliveBetweenTimeMillis)验证连接是否正常,不正常的话,则销毁重新创建。
另外如果发现连接数量低于minidle的情况下,会自动补充连接。
spring:
datasource:
url: xxx
username: xxx
password: xxx
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5
min-idle: 5
max-active: 10
max-wait: 10000
min-evictable-idle-time-millis: 3600000
test-while-idle: true
time-between-eviction-runs-millis: 60000
validation-query: SELECT 1
test-on-borrow: false
test-on-return: false
keep-alive: true
keep-alive-between-time-millis: 3600000