升级阿里云RDS(关系型数据库服务)实例报 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException 问题排查

现象

目前营销数据库使用的是阿里云 MYSQL 数据库,近期需要支持 DBA 对阿里云 RDS 进行升级,升级公告如下:
在这里插入图片描述
凌晨 5 点 10 分进行升级后开始日志报错,错误信息如下:
在这里插入图片描述

问题分析与结论

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

Mysql服务器默认的“wait_timeout”是8小时(也就是默认的值默认是28800秒),即一个connection空闲超过8个小时,Mysql将自动断开该connection,通俗的讲就是一个连接在8小时内没有活动,就会自动断开该连接。而连接池却认为该连接还是有效的(因为并未校验连接的有效性),当应用申请使用该连接时,就会导致上面的报错。

从 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 的配置也能解决问题。

欢迎关注微信公众号:方辰的博客
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
根据提供的引用内容,出现"Could not get a databaseId from dataSource com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure"错误通常是由于数据库连接问题引起的。以下是一些可能的解决方法: 1. 检查数据库连接配置:确保数据库连接配置正确,包括数据库URL、用户名和密码。可以尝试使用相同的配置在本地连接RDS数据库,以确认配置是否正确。 2. 检查网络连接:确保ECS实例RDS数据库在同一地域,并且ECS实例的内网IP已经添加到RDS数据库的白名单中。如果白名单配置正确,但仍然无法连接,可以尝试使用telnet命令检查网络连接是否正常。 3. 检查数据库服务状态:确保RDS数据库服务正常运行。可以通过RDS控制台或命令行工具来检查数据库的状态。 4. 检查数据库连接池配置:如果使用了连接池来管理数据库连接,可以检查连接池的配置是否正确。例如,检查连接池的最大连接数、连接超时时间等参数是否合理。 5. 检查数据库驱动程序:确保使用的数据库驱动程序版本与数据库版本兼容。如果驱动程序版本不匹配,可能会导致连接失败。 6. 检查数据库服务器防火墙:如果数据库服务器上启用了防火墙,确保允许ECS实例的IP地址访问数据库服务器的端口。 7. 检查数据库服务器资源:如果数据库服务器资源不足,可能会导致连接失败。可以检查数据库服务器的CPU、内存和磁盘使用情况,以确保有足够的资源来处理连接请求。 8. 检查数据库日志:查看数据库的错误日志,以获取更多关于连接失败的详细信息。日志文件通常位于数据库服务器的特定目录下。 请注意,以上方法仅提供了一些常见的解决方案,具体的解决方法可能因情况而异。如果问题仍然存在,请提供更多详细信息以便进一步分析和解决。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bboyzqh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值