SpringRetry 프레임 워 크 의 구체 적 인 사용 재 시도

spring retry 는 주로 재 시도 와 용 단 을 실현 합 니 다.
재 시도 에 적합 하지 않 은 장면:
매개 변수 검사 가 합 법 적 이지 않 고 쓰기 작업 등(쓰기 여부 등 을 고려 해 야 함)은 재 시도 에 적합 하지 않 습 니 다.
재 시도 에 적합 한 장면:
원 격 호출 시간 초과,네트워크 갑 작 스 러 운 중단 등 은 다시 시도 할 수 있다.
spring retry 에 서 는 재 시도 가 필요 한 이상 유형 을 지정 하고 재 시도 할 때마다 간격 을 설정 할 수 있 으 며,재 시도 에 실패 하면 재 시도 할 지,녹 일 지 를 설정 할 수 있 습 니 다(재 시도 중단).
환경 구축
SpringRetry 의존 가입,SpringRetry AOP 사용 으로 이 루어 지기 때문에 AOP 가방 가입 도 필요 합 니 다.

<!-- SpringRetry -->
<dependency>
   <groupId>org.springframework.retry</groupId>
   <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-aspects</artifactId>
</dependency>
공식 문서
2.RetryTemplate
2.1 RetryTemplate
Retry Template 는 Retry 기본 동작 을 봉인 했다.
  • org.springframework.retry.support.RetryTemplate
  • RetryTemplate 에서 감청,반환 전략,재 시도 전략 등 을 지정 할 수 있 습 니 다
  • 정상 적 인 new RetryTemplate()만 있 으 면 사용 할 수 있 습 니 다
  • 2.2 RetryListener
    RetryListener 는 실행 중 오류 가 발생 했 을 때의 리 셋 을 지정 합 니 다.
    org.springframework.retry.RetryListener
    
    package org.springframework.retry;
    
    public interface RetryListener {
    
     /**
      *          ,     
      */
     <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback);
    
     /**
      *        (    )  ,     
      */
     <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable);
    
     /**
      *        
      */
     <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable);
    }
    
    
    설정 후 Retry Template 에서 지정
    2.3 후퇴 전략
    2.3.1 FixedBackOffPolicy
    오류 가 발생 했 을 때 얼마나 지연 되 는 지 계속 호출 합 니 다.
    
    FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
    fixedBackOffPolicy.setBackOffPeriod(1000L);
    retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
    설정 후 Retry Template 에서 지정
    2.3.2 ExponentialBackOffPolicy
    오류 가 발생 했 을 때 처음으로 지 정 된 지연 시간 에 따라 지연 한 후 지수 에 따라 지연 합 니 다.
    
    //     ( ),     1s,     2s,   4 ,   8 
    ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
    exponentialBackOffPolicy.setInitialInterval(1000L);
    exponentialBackOffPolicy.setMultiplier(2);
    retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);
    설정 후 Retry Template 에서 지정
    2.4 재 시도 전략
    재 시도 정책 은 오류 가 발생 했 을 때 재 시도 횟수 를 지정 합 니 다.
    
    //     
    SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
    retryPolicy.setMaxAttempts(5);
    retryTemplate.setRetryPolicy(retryPolicy);
    
    
    설정 후 Retry Template 에서 지정
    2.5 RetryCallback
    retry Callback 이 retry Template.execute 일 때 실행 하 는 리 셋
    
    public final <T, E extends Throwable> T execute(RetryCallback<T, E> retryCallback) throws E
    
    

    2.6 핵심 사용
    Retry Template 를 사용 하여 간단하게 사용 할 수 있 습 니 다.
    retryTemplate 설정
  • 반환 정책 을 ExponentialBackOffPolicy 로 지정 합 니 다
  • 다시 시도 전략 을 Simple Retry Policy 로 지정 합 니 다
  • 지 정 된 모니터 RetryListener
    
    import com.codecoord.util.PrintUtil;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.retry.RetryCallback;
    import org.springframework.retry.RetryContext;
    import org.springframework.retry.RetryListener;
    import org.springframework.retry.backoff.ExponentialBackOffPolicy;
    import org.springframework.retry.policy.SimpleRetryPolicy;
    import org.springframework.retry.support.RetryTemplate;
    
    @Configuration
    public class RetryTemplateConfig {
    
        /**
         *   retryTemplate
         */
        @Bean
        public RetryTemplate retryTemplate() {
            RetryTemplate retryTemplate = new RetryTemplate();
    
            ///       ( )
           /* FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
            fixedBackOffPolicy.setBackOffPeriod(1000L);
            retryTemplate.setBackOffPolicy(fixedBackOffPolicy);*/
    
            //     ( ),     1s,     2s
            ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
            exponentialBackOffPolicy.setInitialInterval(1000L);
            exponentialBackOffPolicy.setMultiplier(2);
            retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);
    
            //     
            SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
            retryPolicy.setMaxAttempts(5);
            retryTemplate.setRetryPolicy(retryPolicy);
    
            //      ,open close             
            RetryListener[] listeners = {
                    new RetryListener() {
                        @Override
                        public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
                            PrintUtil.print("open");
                            return true;
                        }
                        @Override
                        public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback,
                                Throwable throwable) {
                            PrintUtil.print("close");
                        }
                        @Override
                        public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback,
                                Throwable throwable) {
                            PrintUtil.print("onError");
                        }
                    }
            };
            retryTemplate.setListeners(listeners);
    
            return retryTemplate;
        }
    }
    controller 에 Retry Template 를 주입 하여 사용 하거나 service 에서 도 사용 할 수 있 습 니 다.
    
    @RestController
    public class SpringRetryController {
        @Resource
        private RetryTemplate retryTemplate;
        private static int count = 0;
    
        @RequestMapping("/retry")
        public Object retry() {
            try {
                count = 0;
                retryTemplate.execute((RetryCallback<Void, RuntimeException>) context -> {
                    //     
                    // ....
                    //       
                    ++count;
                    throw new RuntimeException("    ");
                });
            } catch (RuntimeException e) {
                System.out.println("Exception");
            }
    
            return "retry = " + count;
        }
    }
    retry 인터페이스 에 접근 한 후 로그 출력 을 관찰 합 니 다.
    18:27:20.648 - http-nio-8888-exec-1 - open
    18:27:20.649-http-nio-8888-exec-1-retryTemplate.execute 집행
    18:27:20.649 - http-nio-8888-exec-1 - onError
    18:27:21.658-http-nio-8888-exec-1-retryTemplate.execute 집행
    18:27:21.658 - http-nio-8888-exec-1 - onError
    18:27:23.670-http-nio-8888-exec-1-retryTemplate.execute 집행
    18:27:23.670 - http-nio-8888-exec-1 - onError
    18:27:27.679-http-nio-8888-exec-1-retryTemplate.execute 집행
    18:27:27.679 - http-nio-8888-exec-1 - onError
    18:27:35.681-http-nio-8888-exec-1-retryTemplate.execute 집행
    18:27:35.681 - http-nio-8888-exec-1 - onError
    18:27:35.681 - http-nio-8888-exec-1 - close
    3.EnableRetry
    @Enableretry 에서 재 시 도 를 시작 합 니 다.클래스 에서 지정 한 방법 은 기본적으로 실 행 됩 니 다.세 번 다시 시도 합 니 다.
    service 를 정의 하고@EnableRetry 주석 과 지정@Retryable 을 엽 니 다.다시 시도 하면 다음 절 을 참고 할 수 있 습 니 다.
    
    import org.springframework.retry.annotation.Retryable;
    
    public interface RetryService {
    
        /**
         *       
         */
        @Retryable
        void retryServiceCall();
    }
    
    
    
    import org.springframework.retry.annotation.EnableRetry;
    import org.springframework.stereotype.Service;
    
    @EnableRetry
    @Service
    public class RetryServiceImpl implements RetryService {
    
        @Override
        public void retryServiceCall() {
            PrintUtil.print("    ..");
            throw new RuntimeException("    ");
        }
    }
    controller 에 service 주입
    
    @RequestMapping("/retryAnnotation")
    public Object retryAnnotation() {
        retryService.retryServiceCall();
        return "retryAnnotation";
    }
    
    
    기본 값 으로 다시 시도 합 니 다.
    18:46:48.721-http-nio-8888-exec-1-방법 호출..
    18:46:49.724-http-nio-8888-exec-1-방법 호출...
    18:46:50.730-http-nio-8888-exec-1-방법 호출...
    java.lang.Runtime 예외:수 동 이상
    4.Retryable
    재 시도 가 필요 한 방법 에 대한 주해
    다음 몇 가지 속성 이 있 습 니 다.
    Retryable 주해 파라미터
  • value:발생 한 이상 을 지정 하여 재 시도 합 니 다
  • include:value 와 마찬가지 로 기본 값 이 비어 있 습 니 다.exclude 도 비어 있 을 때 모든 이상 을 다시 시도 합 니 다
  • exclude:이상 을 지정 하여 다시 시도 하지 않 습 니 다.기본 값 은 비어 있 습 니 다.include 도 비어 있 을 때 모든 이상 을 다시 시도 합 니 다
  • maxAttemps:재 시도 횟수,기본 값 34.567917.backoff:보상 체 제 를 다시 시도 하고 기본 값 은 없습니다@Backoff  주해 재 시도 보상 전략
  • 인 자 를 설정 하지 않 을 때 기본적으로 FixedBackOffPolicy(대기 시간 지정)를 사용 하고 1000 ms 를 다시 시도 합 니 다
  • delay 를 설정 하고 Fixed Back OffPolicy(delay 와 max Dealy 를 지정 할 때 이 두 값 사이 의 균일 한 분 포 를 다시 시도 합 니 다)
  • delay,maxDealy,multiplier 를 설정 하고 ExponentialBackOffPolicy(지수 급 재 시도 간격의 실현)를 사용 합 니 다.multiplier 는 지연 배 수 를 지정 합 니 다.예 를 들 어 delay=5000 L,multiplier=2 는 첫 번 째 재 시도 가 5 초,두 번 째 는 10 초,세 번 째 는 20 초 입 니 다
  • 
    @Target({ ElementType.METHOD, ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Retryable {
    
     /**
      * Retry interceptor bean name to be applied for retryable method. Is mutually
      * exclusive with other attributes.
      * @return the retry interceptor bean name
      */
     String interceptor() default "";
    
     /**
      * Exception types that are retryable. Synonym for includes(). Defaults to empty (and
      * if excludes is also empty all exceptions are retried).
      * @return exception types to retry
      */
     Class<? extends Throwable>[] value() default {};
    
     /**
      * Exception types that are retryable. Defaults to empty (and if excludes is also
      * empty all exceptions are retried).
      * @return exception types to retry
      */
     Class<? extends Throwable>[] include() default {};
    
     /**
      * Exception types that are not retryable. Defaults to empty (and if includes is also
      * empty all exceptions are retried).
      * If includes is empty but excludes is not, all not excluded exceptions are retried
      * @return exception types not to retry
      */
     Class<? extends Throwable>[] exclude() default {};
    
     /**
      * A unique label for statistics reporting. If not provided the caller may choose to
      * ignore it, or provide a default.
      *
      * @return the label for the statistics
      */
     String label() default "";
    
     /**
      * Flag to say that the retry is stateful: i.e. exceptions are re-thrown, but the
      * retry policy is applied with the same policy to subsequent invocations with the
      * same arguments. If false then retryable exceptions are not re-thrown.
      * @return true if retry is stateful, default false
      */
     boolean stateful() default false;
    
     /**
      * @return the maximum number of attempts (including the first failure), defaults to 3
      */
     int maxAttempts() default 3;
    
     /**
      * @return an expression evaluated to the maximum number of attempts (including the first failure), defaults to 3
      * Overrides {@link #maxAttempts()}.
      * @date 1.2
      */
     String maxAttemptsExpression() default "";
    
     /**
      * Specify the backoff properties for retrying this operation. The default is a
      * simple {@link Backoff} specification with no properties - see it's documentation
      * for defaults.
      * @return a backoff specification
      */
     Backoff backoff() default @Backoff();
    
     /**
      * Specify an expression to be evaluated after the {@code SimpleRetryPolicy.canRetry()}
      * returns true - can be used to conditionally suppress the retry. Only invoked after
      * an exception is thrown. The root object for the evaluation is the last {@code Throwable}.
      * Other beans in the context can be referenced.
      * For example:
      * <pre class=code>
      *  {@code "message.contains('you can retry this')"}.
      * </pre>
      * and
      * <pre class=code>
      *  {@code "@someBean.shouldRetry(#root)"}.
      * </pre>
      * @return the expression.
      * @date 1.2
      */
     String exceptionExpression() default "";
    
     /**
      * Bean names of retry listeners to use instead of default ones defined in Spring context
      * @return retry listeners bean names
      */
     String[] listeners() default {};
    
    }
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Backoff {
    
     /**
      * Synonym for {@link #delay()}.
      *
      * @return the delay in milliseconds (default 1000)
      */
     long value() default 1000;
    
     /**
      * A canonical backoff period. Used as an initial value in the exponential case, and
      * as a minimum value in the uniform case.
      * @return the initial or canonical backoff period in milliseconds (default 1000)
      */
     long delay() default 0;
    
     /**
      * The maximimum wait (in milliseconds) between retries. If less than the
      * {@link #delay()} then the default of
      * {@value org.springframework.retry.backoff.ExponentialBackOffPolicy#DEFAULT_MAX_INTERVAL}
      * is applied.
      *
      * @return the maximum delay between retries (default 0 = ignored)
      */
     long maxDelay() default 0;
    
     /**
      * If positive, then used as a multiplier for generating the next delay for backoff.
      *
      * @return a multiplier to use to calculate the next backoff delay (default 0 =
      * ignored)
      */
     double multiplier() default 0;
    
     /**
      * An expression evaluating to the canonical backoff period. Used as an initial value
      * in the exponential case, and as a minimum value in the uniform case. Overrides
      * {@link #delay()}.
      * @return the initial or canonical backoff period in milliseconds.
      * @date 1.2
      */
     String delayExpression() default "";
    
     /**
      * An expression evaluating to the maximimum wait (in milliseconds) between retries.
      * If less than the {@link #delay()} then the default of
      * {@value org.springframework.retry.backoff.ExponentialBackOffPolicy#DEFAULT_MAX_INTERVAL}
      * is applied. Overrides {@link #maxDelay()}
      *
      * @return the maximum delay between retries (default 0 = ignored)
      * @date 1.2
      */
     String maxDelayExpression() default "";
    
     /**
      * Evaluates to a vaule used as a multiplier for generating the next delay for
      * backoff. Overrides {@link #multiplier()}.
      *
      * @return a multiplier expression to use to calculate the next backoff delay (default
      * 0 = ignored)
      * @date 1.2
      */
     String multiplierExpression() default "";
    
     /**
      * In the exponential case ({@link #multiplier()} &gt; 0) set this to true to have the
      * backoff delays randomized, so that the maximum delay is multiplier times the
      * previous delay and the distribution is uniform between the two values.
      *
      * @return the flag to signal randomization is required (default false)
      */
     boolean random() default false;
    }
    재 시도 가 필요 한 방법 에 대응 하 는 재 시도 횟수,재 시도 이상 유형,재 시도 지연 시간,재 시도 전략,방법 감청 이름 을 설정 합 니 다.
    
    @Component
    public class PlatformClassService {
        @Retryable(
            //          
            value = {Exception.class},
            //       
            maxAttempts = 5,
            //         
            backoff = @Backoff(delay = 500),
            //         
            listeners = "retryListener"
        )
        public void call() {
            System.out.println("call...");
            throw new RuntimeException("    ");
        }
    }
    
    //     2 ,      1.5     ,     4
    @Retryable(value = {Exception.class}, maxAttempts = 4, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
    
    
    감청 방법,설정 클래스 에서 설정
    
    /**
      *     
      */
    @Bean
    public RetryListener retryListener() {
        return new RetryListener() {
            @Override
            public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
                System.out.println("open context = " + context + ", callback = " + callback);
                //   true        
                return true;
            }
    
            @Override
            public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback,
                                                       Throwable throwable) {
                System.out.println("close context = " + context + ", callback = " + callback);
            }
            @Override
            public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback,
                                                         Throwable throwable) {
                System.out.println("onError context = " + context + ", callback = " + callback);
            }
        };
    }
    호출 서비스
    
    @RestController
    public class SpringRetryController {
        @Resource
        private PlatformClassService platformClassService;
        
        @RequestMapping("/retryPlatformCall")
        public Object retryPlatformCall() {
            try {
                platformClassService.call();
            } catch (Exception e) {
                return "      ";
            }
            return "retryPlatformCall";
        }
    }
    호출 결과

    스프링 리 트 리 재 시도 프레임 워 크 에 대한 구체 적 인 사용 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.스프링 리 트 리 재 시도 프레임 워 크 에 관 한 더 많은 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

    좋은 웹페이지 즐겨찾기