我用的是个人阿里云测试机。查询实时输出日志,看到数据库连接失败后一直在重连服务器。一开始以为是重复攻击,后来重启服务后,一直没有重连。看下面输出日志:2022-02-0911:04:58.896ERROR16876---[eate-1550991149]com.alibaba.druid.pool.DruidDataSource:createconnectionSQLException,url:jdbc:mysql://47.98.67,98:1234/test?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC,errorCode1045,state28000java.sql.SQLException:com.mysql用户'root'@'113.90.123.76'(使用密码:YES)的访问被拒绝.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)~[mysql-connector-java-8.0.16.jar:8.0.16]在com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)~[mysql-connector-java-8.0.16.jar:8.0.16]在com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)~[mysql-connector-java-8.0.16.jar:8.0.16]在com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835)~[mysql-connector-java-8.0.16.jar:8.0.16]在com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:455)~[mysql-connector-java-8.0.16.jar:8.0.16]在com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)~[mysql-connector-java-8.0.16.jar:8.0.16]在com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199)~[mysql-connector-java-8.0.16.jar:8.0.16]在com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:156)~[druid-1.1.10.jar:1.1.10]在com.alibaba.druid.filter.stat.StatFilter.connection_connect(StatFilter.java:218)~[druid-1.1.10.jar:1.1.10]在com.alibaba.druid.filter.FilterChainImpl.connection_connect(FilterChainImpl.java:150)~[druid-1.1.10.jar:1.1.10]在com.alibaba.druid.pool。DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1560)~[druid-1.1.10.jar:1.1.10]在com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1623)~[druid-1.1.10.jar:1.1.10]在com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2468)~[druid-1.1.10.jar:1.1.10]注意上面一直提示druid数据库连接池,这里可能是druid连接的问题pool,然后去掉druid的maven依赖后,请求接口就不会出现重连问题了druid重连的原因在上面的源码中找到。最后一行DruidDataSource.java:2468位于源代码中。CreateConnectionThread创建一个连接线程。看一下CreateConnectionThread的源码:publicclassCreateConnectionThreadextendsThread{publicCreateConnectionThread(Stringname){super(name);这个.setDaemon(true);}publicvoidrun(){initedLatch.countDown();longlastDiscardCount=0;int错误计数=0;for(;;){//addLasttry{lock.lockInterruptibly();}catch(InterruptedExceptione2){中断;}longdiscardCount=DruidDataSource.this.discardCount;booleandiscardChanged=discardCount-lastDiscardCount>0;lastDiscardCount=discardCount;尝试{布尔空等待=真;如果(创建错误!=null&&poolingCount==0&&!discardChanged){emptyWait=false;}if(emptyWait&&asyncInit&&createCount=notEmptyWaitThreadCount//&&!(keepAlive&&activeCount+poolingCount=maxActive){empty.await();继续;}}}赶上(InterruptedExceptione){lastCreateError=e;lastErrorTimeMillis=System.currentTimeMillis();if(!closing){LOG.error("createconnectionThreadInterrupted,url:"+jdbcUrl,e);}休息;}最后{lock.unlock();}PhysicalConnectionInfoconnection=null;尝试{connection=createPhysicalConnection();setFailContinuous(假);}catch(SQLExceptione){LOG.error("创建连接SQLException,url:"+jdbcUrl+",errorCode"+e.getErrorCode()+",state"+e.getSQLState(),e);错误计数++;如果(errorCount>connectionErrorRetryAttempts&&timeBetweenConnectErrorMillis>0){//故障转移重试尝试setFailContinuous(true);如果(failFast){lock.lock();尝试{notEmpty.signalAll();}最后{lock.unlock();}}如果(breakAfterAcquireFailure){中断;}尝试{Thread.sleep(timeBetweenConnectErrorMillis);}catch(InterruptedExceptioninterruptEx){中断;}}}catch(RuntimeExceptione){LOG.error("createconnectionRuntimeException",e);设置失败连续(真);继续等;}catch(Errore){LOG.error("创建连接错误",e);设置失败连续(真);休息;}如果(连接==null){继续;}布尔结果=put(connection);(!result){JdbcUtils.close(connection.getPhysicalConnection());LOG.info("将物理连接连接到池失败。");}错误计数=0;//reseterrorCount}}}这是一个多线程的类,在run方法中设置了无限for循环for(;;){},log报错位置信息:connection=createPhysicalConnection();如果满足条件errorCount>connectionErrorRetryAttempts&&timeBetweenConnectErrorMillis>0会再次尝试重连看看这几个参数的含义:errorCount错误计数在run方法初始化时为零,每次连接失败,会自动加1connectionErrorRetryAttempts连接错误重试次数,默认值为1受保护的intconnectionErrorRetryAttempts=1;timeBetweenConnectErrorMillis连接间隔时间,以毫秒为单位。默认值为500。受保护的挥发性长时间timeBetWeenconNectErmillis=default_time_betwein_connect_error_millis;publicstatictastfinalfinalfinalfinaldemdemdemdemdemdemdemdem_connect_connect_error_millis=500;500;我们acquire-failure设置成true,配置application.properties文件如下:spring.datasource.druid.break-after-acquire-failure=true如果要多次尝试连接,需要设置connection-error-retry-attempts,只有当errorCount大于connectionErrorRetryAttempts时才会进入condition,循环才会中断。在application.properties文件中,配置如下:spring.datasource.druid.connection-error-retry-attempts=3总结一下,在使用多线程连接数据时,由于使用了无限循环连接,连接druid数据库失败,其中连接失败时需要中断连接,需要设置break-after-acquire-failure为true。设置后,如果数据库连接不成功,则不会继续重试。如果要设置重连次数,需要设置connection-error-retry-attempts。如果您觉得文章对您有帮助,请点个赞吧!