springboot druid 데이터베이스 연결 풀이 연결 실패 후 계속 다시 연결되는 문제를 해결하는 방법

王林
풀어 주다: 2023-05-21 11:28:25
앞으로
3089명이 탐색했습니다.

개인 Alibaba Cloud 테스트 머신을 사용했을 때 실시간 출력 로그를 볼 때 데이터베이스 연결이 실패한 후 서버가 계속 재연결을 시도하는 것을 발견했습니다. 처음에는 시스템이 지속적인 공격을 받고 있는 줄 알았으나, 서비스를 다시 시작한 이후에는 더 이상 지속적인 재접속이 발생하지 않았습니다. 다음 출력 로그를 살펴보십시오.

2022-02-09 11:04:58.896 ERROR 16876 --- [eate-1550991149] com.alibaba.druid.pool.DruidDataSource : 연결 생성 SQLException, url: jdbc:mysql: // 47.98.67,98:1234/test?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC, errorCode 1045, 상태 28000

java.sql.SQLException: 'root'@'113.90.123.76' 사용자에 대한 액세스가 거부되었습니다(사용 비밀번호: YES)
com.mysql.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 maven 종속성을 제거한 후에는 요청 인터페이스에 다시 연결 문제가 없을 것입니다.

druid 재연결 이유

위 소스 코드에서 DruidDataSource.java:2468의 마지막 줄을 찾으세요. CreateConnectionThread가 연결 스레드를 생성합니다. CreateConnectionThread 소스 코드를 살펴보세요:

public class CreateConnectionThread extends Thread { public CreateConnectionThread(String name){ super(name); this.setDaemon(true); } public void run() { initedLatch.countDown(); long lastDiscardCount = 0; int errorCount = 0; for (;;) { // addLast try { lock.lockInterruptibly(); } catch (InterruptedException e2) { break; } long discardCount = DruidDataSource.this.discardCount; boolean discardChanged = discardCount - lastDiscardCount > 0; lastDiscardCount = discardCount; try { boolean emptyWait = true; if (createError != null && poolingCount == 0 && !discardChanged) { emptyWait = false; } if (emptyWait && asyncInit && createCount < initialSize) { emptyWait = false; } if (emptyWait) { // 必须存在线程等待,才创建连接 if (poolingCount >= notEmptyWaitThreadCount // && !(keepAlive && activeCount + poolingCount < minIdle)) { empty.await(); } // 防止创建超过maxActive数量的连接 if (activeCount + poolingCount >= maxActive) { empty.await(); continue; } } } catch (InterruptedException e) { lastCreateError = e; lastErrorTimeMillis = System.currentTimeMillis(); if (!closing) { LOG.error("create connection Thread Interrupted, url: " + jdbcUrl, e); } break; } finally { lock.unlock(); } PhysicalConnectionInfo connection = null; try { connection = createPhysicalConnection(); setFailContinuous(false); } catch (SQLException e) { LOG.error("create connection SQLException, url: " + jdbcUrl + ", errorCode " + e.getErrorCode() + ", state " + e.getSQLState(), e); errorCount++; if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) { // fail over retry attempts setFailContinuous(true); if (failFast) { lock.lock(); try { notEmpty.signalAll(); } finally { lock.unlock(); } } if (breakAfterAcquireFailure) { break; } 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; } boolean result = put(connection); if (!result) { JdbcUtils.close(connection.getPhysicalConnection()); LOG.info("put physical connection to pool failed."); } errorCount = 0; // reset errorCount } } }
로그인 후 복사

이것은 다중 스레드 클래스 및 run 메서드에서 (;;) {}에 대한 무제한 for 루프가 설정되고 로그 오류 위치 정보는 다음과 같습니다.

connection = createPhysicalConnection();
로그인 후 복사

조건이 충족되면 errorCount > 0이면 다시 연결이 시도됩니다. 의미:

errorCount 연결이 실패할 때마다 자동으로 1

이 추가됩니다.

connectionErrorRetryAttempts

연결 오류 재시도 횟수, 기본값은 1입니다.

protected int connectionErrorRetryAttempts = 1;
로그인 후 복사

timeBetweenConnectErrorMillis

연결 간격 시간(밀리초)입니다. 기본값은 500입니다.

protected volatile long timeBetweenConnectErrorMillis = DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS; public static final long DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS = 500;
로그인 후 복사

데이터베이스 연결에 실패한 후 내부를 침입해야 합니다. 그중

if (breakAfterAcquireFailure) { break; }
로그인 후 복사

는 break-after-acquire-failure를 true로 변경하고 application.properties 파일에서 다음과 같이 구성합니다.

spring.datasource.druid.break-after-acquire-failure=true
로그인 후 복사

더 여러 번 연결을 시도하려면 연결 오류-재시도를 설정해야 합니다. errorCount가 연결 오류RetryAttempts보다 크면 조건이 입력되고 루프가 중단됩니다. 다음은 application.properties 파일의 구성입니다.

spring.datasource.druid.connection-error-retry-attempts=3
로그인 후 복사

위 내용은 springboot druid 데이터베이스 연결 풀이 연결 실패 후 계속 다시 연결되는 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:yisu.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!