개발/spring

[retry] spring-retry 다시 복기

방푸린 2024. 5. 24. 16:40
반응형

springframework에서 제공하는 spring retry에 대해 알아보자

maven repo: https://mvnrepository.com/artifact/org.springframework.retry/spring-retry

 

spring aspect 라이브러리를 사용할 수도 있는데, 해당 라이브러리는 springboot starter에 있을 수 있기에 한번 확인하고 넣는 게 좋다.

springboot2.7.3 기준 5.3.24 버전이 들어가 있다.

 

관련 어노테이션을 사용하려면 아래처럼 enable 시켜줘야 한다.

import org.springframework.context.annotation.Configuration;
import org.springframework.retry.annotation.EnableRetry;

@Configuration
@EnableRetry
public class AppConfig {
}

실행 원리는 proxy!!

 

재시도를 해야 하는 함수에 @Retryable을 달아주고

재시도 시 실행해야하는 함수에 @Recover를 달아준다.

import org.springframework.retry.annotation.Recover;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Retryable(value = { SomeTransientException.class }, maxAttempts = 3)
    public void performTask() throws SomeTransientException {
        // Your logic here
        System.out.println("Trying to perform task...");
        throw new SomeTransientException("Temporary failure");
    }

    @Recover
    public void recover(SomeTransientException e) {
        // Recovery logic here
        System.out.println("Recovering from failure: " + e.getMessage());
    }
}

api에러 뿐만 아니라 아래와 같이 디비 에러에도 가능. IO에러 등등 많이 커버한다.. @Retryable에서 throw 하는 에러 타입과 @Recover에서 받는 에러타입이 반드시 같아야 한다.

@Service
public interface MyService { 

    @Retryable(retryFor = SQLException.class)
    void retryServiceWithRecovery(String sql) throws SQLException; 

    @Recover
    void recover(SQLException e, String sql); 
}

Retryable 어노테이션에는 어떤 exception이 발생할 때 재시도를 할지와 최대 몇 번 실행할지를 지정해 줄 수 있다.

  • maxAttempts: 실패가 n번 나면 recover 함수를 실행한다.
    • default: 3
  • backoff: 재실행하고 n초 쉬었다가 재실행(단위: ms)
    • default:  a fixed delay of 1000ms
  • multiplier: 재시도와 재시도 사이의 시간 간극이 n배로 점점 멀어짐
    • default: 0(무시)
  • BackOffPolicy: 아래처럼 설정 값들에 따라 재시도 간격이 달라진다.
    • With no explicit settings the default is a fixed delay of 1000ms
    • Only the delay() set: the backoff is a fixed delay with that value
    • When delay() and maxDelay() are set the backoff is uniformly distributed between the two values
    • With delay(), maxDelay() and multiplier() the backoff is exponentially growing up to the maximum value
    • If, in addition, the random() flag is set then the multiplier is chosen for each delay from a uniform distribution in [1, multiplier-1]

 

위 값들은 클래스에서 상수 값으로 관리할 수 있지만 공용사용과 환경별 관리를 위헤 프로퍼티 파일로 뺄 수도 있다.

이때 해당 변수 명이 달라지니(ex. maxAttemps -> maxAtempsExpression) 반드시 공식문서를 참고해야 한다!

https://docs.spring.io/spring-retry/docs/api/current/org/springframework/retry/annotation/Retryable.html

 

공통 설정 혹은 더 복잡한 설정을 위해 java config로 설정할 수도 있다.

@Configuration
@EnableRetry
public class RetryConfig {


    @Bean
    public RetryTemplate retryTemplate(){
        RetryTemplate retryTemplate = new RetryTemplate();

        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(3000l);
        
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);

        Map<Class<? extends Throwable>, Boolean> includeExceptions = new HashMap<>();
        includeExceptions.put(CannotAcquireLockException.class, true);

        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(5, includeExceptions);
        retryTemplate.setRetryPolicy(retryPolicy);

        return retryTemplate;
    }
    
}

 

참고로 delay는 간격은 랜덤으로도 줄 수 있다.

@Retryable(
    value = {CannotAcquireLockException.class},
    maxAttempts = 4,
    backoff = @Backoff(random = true, delay = 1000, maxDelay = 5000, multiplier = 2)

 


기본설명:

https://www.baeldung.com/spring-retry

좀더 복잡하게 사용하기:

https://medium.com/@AlexanderObregon/using-springs-retryable-annotation-for-automatic-retries-c1d197bc199f

https://medium.com/@vmoulds01/springboot-retry-random-backoff-136f41a3211a


이럴 수가.. 적으면서 이거 전에 본적 있는데 싶었는데 무려 정리를 했던 적이 있던 것ㅋㅋㅋㅋ

2022.02.04 - [개발/spring] - [retry] spring-retry for auto retry

 

[retry] spring-retry for auto retry

spring-retry? exception이 난 작업에 대해 자동으로 재시도 해주는 스프링 라이브러리이다. 일시적인 connection error 등에 유용하게 사용할 수 있다. 환경: springboot2.6.2 implementation 'org.springframework.retry:spri

bangpurin.tistory.com

 

728x90
반응형