태그(공백으로 구분): druid springboot start autoconfig
Background
검색 및 분석 프로세스
요약
최근 , Alibaba druid를 사용하여 여러 데이터 소스를 연결할 때 실수로 작은 버그를 발견했습니다. github 문제를 제출했는데 공식적으로 수정되었습니다. 문제 주소:
우리가 사용하는 Java 개발 프레임워크가 캡슐화되어 있습니다. 데이터 소스에 대한 프레임워크의 지원은 마스터 및 슬레이브 아키텍처를 기반으로 합니다. 즉, 여러 슬레이브 데이터 소스의 집합일 수 있으며 마스터-슬레이브 쓰기 및 쿼리 전환이 내부적으로 자동으로 수행됩니다.
현재 .net을 Java로 변환하는 중입니다. 특수한 시나리오에서는 새로운 Java 시스템이 두 개의 데이터 소스에 연결되어야 하지만 때로는 sqlserver 데이터를 쿼리해야 합니다. 일부 호환성 데이터를 얻으려면 소스를 사용하세요.
그래서 두 번째 데이터 소스를 구성할 때 시스템 로드에서 오류가 보고되었습니다.
우리는 springboot 프레임워크를 사용하며, springboot 속성을 기반으로 데이터 소스 구성을 구성합니다. 그런 다음 구성을 사용하여 자동 druid daasource Bean을 생성하십시오. 이것은 문제가 되지 않는 것 같습니다.
@Bean(name = "dataSource") @ConfigurationProperties(prefix = "ecommon.order.druid") public DataSource getOrderDataSource() { return new DruidDataSource(); }
springboot가 아닌 경우 일반적으로 모든 속성을 직접 초기화합니다. 구성 파일에서 구성을 로드하고 DruidDataSource 빈을 수동으로 설정합니다.
저는 별 생각 안하고 그냥 이렇게 사용했어요. 그러나 시작 시 Bean을 초기화할 때 오류가 보고되었습니다. maxevictableidletimemillis의 예외는 java.lang.ilegalargumentexception입니다. .
첫 번째 반응은 구성이 잘못되었다는 것입니다. 구성을 확인하세요.##一个连接在池中最小生存的时间(ms) ecommon.order.druid.minEvictableIdleTimeMillis=300000 ##一个连接在池中最大生存的时间(ms) ecommon.order.druid.maxEvictableIdleTimeMillis=600000맞는 것 같은데, 디버그 시에도 같은 문제가 발생합니다. minEvictableIdleTimeMillis 속성과 maxEvictableIdleTimeMillis 속성의 순서는 괜찮은 것 같습니다. 시도해본 후 두 속성의 순서를 바꿨으나 여전히 문제가 발생했습니다.
눈이 먼 상태~_~.
이 문제는 좀 이상하다고 생각합니다. 시간이 중요하기 때문에 오류가 보고된 곳을 직접 찾아 소스 코드를 추적합니다.
github 검색 alibaba druid 홈페이지로 이동하여 직접 git clone하여 오류 프롬프트 위치를 찾습니다. 글로벌 검색 중에 이 예외가 발생하는 곳은 두 곳입니다.One: init method
public void init() throws SQLException { if (maxEvictableIdleTimeMillis < minEvictableIdleTimeMillis) { throw new SQLException("maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis"); }
읽기의 편의를 위해 문제 분석에 쓸모가 없는 init 코드를 삭제했습니다.
public void setMaxEvictableIdleTimeMillis(long maxEvictableIdleTimeMillis) { if (maxEvictableIdleTimeMillis < 1000 * 30) { LOG.error("maxEvictableIdleTimeMillis should be greater than 30000"); } if (maxEvictableIdleTimeMillis < minEvictableIdleTimeMillis) { throw new IllegalArgumentException("maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis"); } this.maxEvictableIdleTimeMillis = maxEvictableIdleTimeMillis; }
그러므로 이 두 곳에 중단점을 두고 디버그하면 기본적으로 문제가 어디에 있는지 알 수 있습니다.
디버깅을 통해 new DruidDataSource()로 직접 데이터 소스를 사용하면 init 메소드로 이동하지 않는다는 것을 발견했습니다. 오류가 발생한 장소에는 입력되지 않습니다. 내 코드 경로가 이 검사를 생성해서는 안 되는 것 같습니다. 계속 실행하여 setMaxEvictableIdleTimeMillis 메소드에서 어떤 일이 발생하는지 확인하세요.
setMaxEvictableIdleTimeMillis 메서드를 수행할 때 minEvictableIdleTimeMillis 속성 값이 1800000인 문제를 발견했습니다.
이 값이 어디서 나오는지 살펴보겠습니다.
protected volatile long minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
public static final long DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS = 1000L * 60L * 30L;
minEvictableIdleTimeMillis 속성에는 기본값이 있습니다. 단위는 ms(밀리초)이므로 여기서 기본값은 30m(분)분입니다.
600000ms로 구성했으므로 1800000보다 작습니다. 그러나 이것은 이상합니다. 우리는 minEvictableIdleTimeMillis 매개변수를 명확하게 설정했습니다. 왜 작동하지 않았나요? 저는 즉시 시퀀스 문제라고 생각했습니다.
그런 다음 디버깅을 계속하세요. 먼저 이 검사를 우회하여 setMinEvictableIdleTimeMillis 메서드가 setMaxEvictableIdleTimeMillis 메서드 다음에 실행되어 이 검사가 구성 순서와 충돌하는지 확인하세요.
디버깅하고 보니 이게 정말 문제네요. 그러다가 지금 우리가 사용하고 있는 프레임워크가 druid를 캡슐화하는 데 어떻게 도움이 되는지 더 궁금했습니다. 프레임워크의 소스 코드를 살펴보면 이 문제를 해결하는 해시코드 정렬이 있다는 것을 알 수 있습니다. (물론 베테랑 드라이버이자 마스터) 여기서는 자세히 설명하지 않겠습니다.
그래서 이 문제를 해결하면 실제로 문제를 해결할 위치를 아는 것은 매우 간단합니다.
One: 먼저 구성된 minEvictableIdleTimeMillis 및 maxEvictableIdleTimeMillis를 가져옵니다.
@Data @EqualsAndHashCode @ConfigurationProperties(prefix = "ecommon.order.druid") public class SqlServerDruidConfig { private Long minEvictableIdleTimeMillis; private Long maxEvictableIdleTimeMillis; }
Two: 그런 다음 이 두 속성을 먼저 직접 설정하면 springboot autoconfig
@Autowired private SqlServerDruidConfig druidConfig; @Bean(name = "dataSource") @ConfigurationProperties(prefix = "ecommon.order.druid") public DataSource getOrderDataSource() { DruidDataSource dataSource = new DruidDataSource(); /**setMinEvictableIdleTimeMillis需要先设置*/ dataSource.setMinEvictableIdleTimeMillis(druidConfig.getMinEvictableIdleTimeMillis()); dataSource.setMaxEvictableIdleTimeMillis(druidConfig.getMaxEvictableIdleTimeMillis()); return dataSource; } @Bean public SqlServerDruidConfig getDruidConfig() { return new SqlServerDruidConfig(); }
문제 분석이 여기서 끝나도 오류가 발생하지 않습니다. 이 작은 버그는 alibaba druid에 의해 수정되었습니다.
수정 방법에 관심이 있으시면 druid에서 autoconfiger 수정에 대한 코드를 참조하세요:갑자기 오픈소스의 이점을 실제로 활용했다는 사실을 깨닫게 되실 겁니다. 함께 사용하고, 문제를 발견하고, 버그를 수정하는 데 함께 참여할 수 있습니다. 이것이 리눅스, git 등 훌륭한 예술 작품을 뒷받침하는 핵심적인 기술적 가치일 수도 있습니다.
위 내용은 alibaba druid를 사용하여 여러 데이터 소스를 연결할 때 발생하는 문제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!