文章目录
密码错误重试导致数据库超慢
有同事把项目的数据库密码配错了,导致其他所有连接该数据库的项目全部连接都获取缓慢了,一个页面加载要花费十几秒。排查mysql连接发现很多connect命令的连接
show full PROCESSLIST
由于连接的host全是我们服务器的ip,所以一开始想到的是服务器是不是被黑了,然后频繁的尝试破解数据库密码
赶紧查了一下是哪个进程在连接数据库
bash
netstat -anp | grep 3306
结果发现pid是我们自己的项目,拉下来代码一看,密码配置的不对
如何避免呢?
druid有个配置是连接重试次数
xml
<!-- 连接错误重试次数,默认是1 -->
<property name="connectionErrorRetryAttempts" value="5"/>
<!-- 达到所配置的connectionErrorRetryAttempts失败次数后,多久重试一次
这个可以配置大一点,给数据库反应时间
-->
<property name="timeBetweenConnectErrorMillis" value="10000"/>
这样配置的话失败5次之后,会休眠10s在进行重试
如果失败5次后不想重试,直接退出呢?这样就算数据库恢复也不会连接到数据库了,可以这样配置
xml
<!-- 连接错误重试次数,默认是1 -->
<property name="connectionErrorRetryAttempts" value="5"/>
<!-- 失败足够次数后直接退出 -->
<property name="breakAfterAcquireFailure" value="true"/>
如果连重试都不想重试呢?那就把重试次数直接设置为0
xml
<!-- 连接错误重试次数,默认是1 -->
<property name="connectionErrorRetryAttempts" value="0"/>
<!-- 失败足够次数后直接退出 -->
<property name="breakAfterAcquireFailure" value="true"/>
druid代码逻辑是
java
errorCount++;
// 重试次数超过connectionErrorRetryAttempts且timeBetweenConnectErrorMillis大于0
if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
// fail over retry attempts
setFailContinuous(true);
if (failFast) {
lock.lock();
try {
notEmpty.signalAll();
} finally {
lock.unlock();
}
}
// 达到该次数直接退出,不再尝试
if (breakAfterAcquireFailure) {
break;
}
// 睡眠timeBetweenConnectErrorMillis后继续尝试
try {
Thread.sleep(timeBetweenConnectErrorMillis);
} catch (InterruptedException interruptEx) {
break;
}
}
} catch (RuntimeException e) {
LOG.error("create connection RuntimeException", e);
setFailContinuous(true);
continue;
} catch (Error e) {
LOG.error("create connection Error", e);
setFailContinuous(true);
break;
}
if (connection == null) {
continue;
}
参考文献