【Java】升级阿里云RDS实例报 CommunicationsException 问题排查

升级阿里云RDS实例报 CommunicationsException 问题排查

bboyzqh发布于 42 分钟前

@[toc]

现象

目前营销数据库使用的是阿里云 MYSQL 数据库,近期需要支持 DBA 对阿里云 RDS 进行升级,升级公告如下:
【Java】升级阿里云RDS实例报 CommunicationsException 问题排查
凌晨 5 点 10 分进行升级后开始日志报错,错误信息如下:
【Java】升级阿里云RDS实例报 CommunicationsException 问题排查

问题分析与结论

一般出现 duridCommunicationsException 原因是由于连接池获取已经失效的连接导致。从 mysql 上来说:

从 druid 配置属性上和连接失效的属性有以下几个:

  • minEvictableIdleTimeMillis:连接空闲时间大于该值并且池中空闲连接大于 minIdle 则关闭该连接。配置中采用的默认值 30 分钟。
  • maxEvictableIdleTimeMillis:连接空闲时间大于该值,不管 minIdle 都关闭该连接。配置中采用的默认值 7 个小时。
  • maxidle:目前 druid 已经废弃了 maxidle 属性,使用 maxActive 和 minIdel 来代替,参考https: //github.com/alibaba/druid/wiki/FAQ,从 druid 配置上看,minIdle 是 50,maxActive 是 400(代码上设置不合理,可调整)。

即理论上 druid 默认连接失效的最大 7 个小时也小于数据库 8 个小时,不会存在配置层面上获取到失效的连接。再从公告上看,有说明:“在迁移过程中会有 30 秒的连接闪断”,说明 rds 闪断后原有的的数据库连接 都已经失效了,而 smc 系统中 druid 连接池还保持着有效状态,所以会导致com.mysql.jdbc.exceptions.jdbc4. CommunicationsException 发生。

解决方案

直接思路时在 druid 线程拿到连接后校验一下就 ok 了,涉及到相关属性有 test- WhileIdle、testOnBorrow,意义如下:

  • testWhileIdle:如果为 true(默认 true),当应用向连接池申请连接,并且 testOnBorrow 为 false 时,连接池将会判断连接是否处于空闲状态,如果是,则验证这条连接是否可用(高效,推荐使用)。
  • testOnBorrow:(默认 false)申请连接时进行连接有效性检查(低效,影响性能),与 testWhileIdle 是差不多的,都是在获取连接的时候测试连接的有效性,如果两者都为 true,则 testOnBorrow 优先 级高,则不会使用到 testWhileIdle。
  • validationQuery:在连接池返回连接给调用者前用来对连接进行验证的查询 SQL,要求为一条查询语句(开启 testWhileIdle 必须要设置 validationQuery)。

druid 配置中增加:

spring.datasource.druid.test-on-borrow=false

spring.datasource.druid.test-while-idle=true

spring.datasource.druid.validation-query=SELECT 1

此时还有一个疑问,在没有配置上述属性的情况下,testWhileIdlel 默认为 true,testOnBorrow 默认 为 false,validationQuery 默认为空,为什么没有强制设置 validationQuery 呢?此时要分 2 个阶段说明问题:

  • durid 初始化阶段:只打了 error,并未中断初始化过程
  • 获取连接过程:校验了 minEvictableIdleTimeMillis 和 maxEvictableIdleTimeMillis,发现 validation- Query 为 null 直接返回了,所以上述配置只需要增加 validationQuery 的配置也能解决问题。

欢迎关注微信公众号:方辰的博客
【Java】升级阿里云RDS实例报 CommunicationsException 问题排查

java

阅读 22发布于 42 分钟前

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议

avatar

bboyzqh

1 声望

0 粉丝

0 条评论

得票时间

avatar

bboyzqh

1 声望

0 粉丝

宣传栏

@[toc]

现象

目前营销数据库使用的是阿里云 MYSQL 数据库,近期需要支持 DBA 对阿里云 RDS 进行升级,升级公告如下:
【Java】升级阿里云RDS实例报 CommunicationsException 问题排查
凌晨 5 点 10 分进行升级后开始日志报错,错误信息如下:
【Java】升级阿里云RDS实例报 CommunicationsException 问题排查

问题分析与结论

一般出现 duridCommunicationsException 原因是由于连接池获取已经失效的连接导致。从 mysql 上来说:

从 druid 配置属性上和连接失效的属性有以下几个:

  • minEvictableIdleTimeMillis:连接空闲时间大于该值并且池中空闲连接大于 minIdle 则关闭该连接。配置中采用的默认值 30 分钟。
  • maxEvictableIdleTimeMillis:连接空闲时间大于该值,不管 minIdle 都关闭该连接。配置中采用的默认值 7 个小时。
  • maxidle:目前 druid 已经废弃了 maxidle 属性,使用 maxActive 和 minIdel 来代替,参考https: //github.com/alibaba/druid/wiki/FAQ,从 druid 配置上看,minIdle 是 50,maxActive 是 400(代码上设置不合理,可调整)。

即理论上 druid 默认连接失效的最大 7 个小时也小于数据库 8 个小时,不会存在配置层面上获取到失效的连接。再从公告上看,有说明:“在迁移过程中会有 30 秒的连接闪断”,说明 rds 闪断后原有的的数据库连接 都已经失效了,而 smc 系统中 druid 连接池还保持着有效状态,所以会导致com.mysql.jdbc.exceptions.jdbc4. CommunicationsException 发生。

解决方案

直接思路时在 druid 线程拿到连接后校验一下就 ok 了,涉及到相关属性有 test- WhileIdle、testOnBorrow,意义如下:

  • testWhileIdle:如果为 true(默认 true),当应用向连接池申请连接,并且 testOnBorrow 为 false 时,连接池将会判断连接是否处于空闲状态,如果是,则验证这条连接是否可用(高效,推荐使用)。
  • testOnBorrow:(默认 false)申请连接时进行连接有效性检查(低效,影响性能),与 testWhileIdle 是差不多的,都是在获取连接的时候测试连接的有效性,如果两者都为 true,则 testOnBorrow 优先 级高,则不会使用到 testWhileIdle。
  • validationQuery:在连接池返回连接给调用者前用来对连接进行验证的查询 SQL,要求为一条查询语句(开启 testWhileIdle 必须要设置 validationQuery)。

druid 配置中增加:

spring.datasource.druid.test-on-borrow=false

spring.datasource.druid.test-while-idle=true

spring.datasource.druid.validation-query=SELECT 1

此时还有一个疑问,在没有配置上述属性的情况下,testWhileIdlel 默认为 true,testOnBorrow 默认 为 false,validationQuery 默认为空,为什么没有强制设置 validationQuery 呢?此时要分 2 个阶段说明问题:

  • durid 初始化阶段:只打了 error,并未中断初始化过程
  • 获取连接过程:校验了 minEvictableIdleTimeMillis 和 maxEvictableIdleTimeMillis,发现 validation- Query 为 null 直接返回了,所以上述配置只需要增加 validationQuery 的配置也能解决问题。

欢迎关注微信公众号:方辰的博客
【Java】升级阿里云RDS实例报 CommunicationsException 问题排查

以上是 【Java】升级阿里云RDS实例报 CommunicationsException 问题排查 的全部内容, 来源链接: www.h5w3.com/114580.html

回到顶部