programing

데이터 소스를 사용할 수 있을 때까지 스프링 재시도 연결

batch 2023. 7. 5. 20:32
반응형

데이터 소스를 사용할 수 있을 때까지 스프링 재시도 연결

SpringBoot 응용 프로그램과 MySQL 데이터베이스를 시작하기 위한 도커 합성 설정이 있습니다.데이터베이스가 먼저 시작되면 응용프로그램이 성공적으로 연결될 수 있습니다.그러나 응용프로그램이 먼저 시작되면 데이터베이스가 아직 존재하지 않으므로 응용프로그램은 다음 예외를 발생시키고 종료됩니다.

app_1       | 2018-05-27 14:15:03.415  INFO 1 --- [           main]
com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
app_1       | 2018-05-27 14:15:06.770 ERROR 1 --- [           main]
com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization
app_1       | com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure

응용프로그램이 시작되기 전에 데이터베이스가 항상 작동하는지 확인하기 위해 도커 합성 파일을 편집할 수 있지만, 응용프로그램이 데이터베이스 주소에 도달할 수 없을 때 이 경우를 직접 처리할 수 있고 즉시 종료되지 않기를 원합니다.

application.properties 파일에서 데이터 소스를 구성하여 여기와 여기에서 답변한 대로 애플리케이션이 데이터베이스에 다시 연결되도록 하는 방법이 있습니다.그러나 데이터 소스에 대한 시작 연결에는 작동하지 않습니다.

SpringBoot 응용 프로그램이 데이터베이스에 성공적으로 연결될 때까지 특정 간격으로 데이터베이스에 대한 연결을 다시 시도하도록 하려면 어떻게 해야 합니까?

히카리 CP 설정initializationFailTimeout속성이 0(0)이거나 음수입니다.여기에 설명된 대로:

initializationFailTimeout

이 속성은 풀을 초기 연결로 성공적으로 시드할 수 없는 경우 풀이 "빠른 실패" 여부를 제어합니다.양수는 초기 연결을 시도하는 데 걸리는 시간(밀리초)으로 간주되며, 이 기간 동안 응용 프로그램 스레드가 차단됩니다.이 시간 초과가 발생하기 전에 연결을 획득할 수 없는 경우 예외가 발생합니다.이 시간 초과는 다음 시간 이후에 적용됩니다.connectionTimeout기간값이 0이면 HikariCP는 연결을 가져오고 유효성을 검사하려고 시도합니다.연결을 얻었지만 유효성 검사에 실패하면 예외가 느려지고 풀이 시작되지 않습니다.그러나 연결을 얻을 수 없는 경우 풀이 시작되지만 나중에 연결을 얻는 작업이 실패할 수 있습니다.값이 0보다 작으면 초기 연결 시도가 무시되고 백그라운드에서 연결을 가져오는 동안 풀이 즉시 시작됩니다.따라서 나중에 연결을 얻으려는 시도가 실패할 수 있습니다.기본값: 1

특정 연결 라이브러리나 특정 데이터베이스에 의존하지 않는 다른 방법이 있습니다.다음을 사용해야 합니다.spring-retry이 접근법으로 원하는 행동을 달성하기 위해

먼저 종속성에 스프링 재시도를 추가해야 합니다.

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>${spring-retry.version}</version>
</dependency>

그런 다음 장식기를 만들 수 있습니다.DataSource그것은 연장될 것입니다.AbstractDataSource과 같이 래와같이아같::

@Slf4j
@RequiredArgsConstructor
public class RetryableDataSource extends AbstractDataSource {

    private final DataSource dataSource;

    @Override
    @Retryable(maxAttempts = 5, backoff = @Backoff(multiplier = 1.3, maxDelay = 10000))
    public Connection getConnection() throws SQLException {
        log.info("getting connection ...");
        return dataSource.getConnection();
    }

    @Override
    @Retryable(maxAttempts = 5, backoff = @Backoff(multiplier = 2.3, maxDelay = 10000))
    public Connection getConnection(String username, String password) throws SQLException {
        log.info("getting connection by username and password ...");
        return dataSource.getConnection(username, password);
    }
}

사용자 소스 하여 사용자 정의 데이터 소스 장식기를 .BeanPostProcessor:

@Slf4j
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Component
public class RetryableDatabasePostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof DataSource) {
            log.info("-----> configuring a retryable datasource for beanName = {}", beanName);
            return new RetryableDataSource((DataSource) bean);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

하려면 Spring retry를 추가해야 .@EnableRetry 주석, 예 프링주클대래한주석, 예:

@EnableRetry
@SpringBootApplication
public class RetryableDbConnectionApplication {

    public static void main(String[] args) {
        SpringApplication.run(RetryableDbConnectionApplication.class, args);
    }

}

언급URL : https://stackoverflow.com/questions/50553352/spring-retry-connection-until-datasource-is-available

반응형