Spring 오류 이상 재 시도 프레임 워 크 guava - 재 시도

홈 페이지:https://github.com/rholder/guava-retrying
Maven:https://mvnrepository.com/artifact/com.github.rholder/guava-retrying
다음 예 는 Spring Boot 를 기반 으로 하지만 모두 Spring 프로젝트 에 사용 할 수 있 습 니 다.현재 최신 판 은 2.0.0 이다.
통합 단계:
POM 도입:
        
        <dependency>
            <groupId>com.github.rholdergroupId>
            <artifactId>guava-retryingartifactId>
            <version>2.0.0version>
        dependency>

익명 내부 클래스 를 기반 으로 직접 작업 합 니 다.
package com.jsoft.springboottest.springboottest1.controller;

import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.github.rholder.retry.RetryException;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import com.google.common.base.Predicates;

@RestController
public class TestController {
    
    private static final Logger logger = LoggerFactory.getLogger(TestController.class);
    
    @RequestMapping("/show")
    public String show(){        
        Retryer retryer = RetryerBuilder.newBuilder()
                .retryIfResult(Predicates.isNull())//           
                .retryIfExceptionOfType(Exception.class)//        
                .retryIfRuntimeException()//        
                .withStopStrategy(StopStrategies.stopAfterAttempt(5))//     5 ,            
                .withWaitStrategy(WaitStrategies.fixedWait(5L, TimeUnit.SECONDS))//         ,5 
                .build();
        try {
            retryer.call(new Callable() {
                int i = 0;

                @Override
                public Boolean call() throws Exception {
                    i++;
                    logger.info(" {}   !", i);
                    // do something
                    if (i<6) {//    2 
                        logger.info("      !");
                        throw new IOException("  ");
                    }
                    logger.info("      !");
                    return true;                   
                }
            });
        } catch (RetryException e) {
            logger.info("      ", e);
        } catch (ExecutionException e) {
            logger.info("      ", e);
        }
        
        return "Hello World";        
    }


}

예제 프로젝트:https://github.com/easonjim/5_java_example/tree/master/springboottest/springboottest5
상세 한 소개:
필드 사용
일상적인 개발 에서 우 리 는 외부 서비스 와 인 터 페 이 스 를 호출 해 야 하 는 장면 을 자주 만난다.외부 서 비 스 는 호출 자 에 게 일반적으로 신뢰 할 수 없 는 것 이다. 특히 네트워크 환경 이 비교적 좋 지 않 은 상황 에서 네트워크 디 더 링 은 요청 시간 초과 등 이상 상황 을 초래 하기 쉬 우 므 로 이 럴 때 실패 재 시도 전략 을 사용 하여 API 인 터 페 이 스 를 다시 호출 해 야 한다.재 시도 전략 은 서비스 관리 에 있어 서도 광범 위 하 게 사용 되 고 정기 적 인 검 사 를 통 해 서비스 가 생존 하 는 지 확인 합 니 다 (Active).
Guava Retrying 은 유연 하고 편리 한 재 시도 구성 요소 로 여러 가지 재 시도 전략 을 포함 하고 확장 이 매우 쉽다.
작가 의 말로 말 하면
This is a small extension to Google’s Guava library to allow for the creation of configurable retrying strategies for an arbitrary function call, such as something that talks to a remote service with flaky uptime.
Guava - rettrying 을 사용 하면 사용자 정의 로 재 시도 할 수 있 고 매번 재 시도 의 결과 와 행 위 를 감시 할 수 있 습 니 다. 가장 중요 한 Guava 스타일 을 바탕 으로 하 는 재 시도 방식 은 정말 편리 합 니 다.
코드 예제
다음은 guava-retrying 의 사용 방식 을 간단하게 보 여 줍 니 다.
던 지기 IOException 하면 다시 시도 하고, 되 돌아 오 는 결과 null 또는 2 와 같 으 면 다시 시도 하 며, 고정 대기 시간 은 300 ms 로 최대 3 회 시도 한다. 
Callable task = new Callable() {
    @Override
    public Integer call() throws Exception {
        return 2;
    }
};

Retryer retryer = RetryerBuilder.newBuilder()
        .retryIfResult(Predicates.isNull())
        .retryIfResult(Predicates.equalTo(2))
        .retryIfExceptionOfType(IOException.class)
        .withStopStrategy(StopStrategies.stopAfterAttempt(3))
        .withWaitStrategy(WaitStrategies.fixedWait(300, TimeUnit.MILLISECONDS))
        .build();
try {
    retryer.call(task);
} catch (ExecutionException e) {
    e.printStackTrace();
} catch (RetryException e) {
    e.printStackTrace();
}

이상 이 발생 하면 재 시도 가 실 행 됩 니 다. 매번 작업 수행 의 최 장 실행 시간 은 3s 로 제한 되 어 있 습 니 다. 재 시도 간격 은 초기 에는 3s 이 고 최대 1 분 동안 재 시도 합 니 다. 재 시도 횟수 가 증가 함 에 따라 매번 1s 씩 증가 합 니 다. 재 시도 에 실패 할 때마다 로 그 를 인쇄 합 니 다.
@Override
public Integer call() throws Exception {
        return 2;
    }
};

Retryer retryer = RetryerBuilder.newBuilder()
        .retryIfException()
        .withStopStrategy(StopStrategies.stopAfterDelay(30,TimeUnit.SECONDS))
        .withWaitStrategy(WaitStrategies.incrementingWait(3, TimeUnit.SECONDS,1,TimeUnit.SECONDS))
        .withAttemptTimeLimiter(AttemptTimeLimiters.fixedTimeLimit(3,TimeUnit.SECONDS))
        .withRetryListener(new RetryListener() {
            @Override
            public  void onRetry(Attempt attempt) {
                if (attempt.hasException()){
                    attempt.getExceptionCause().printStackTrace();
                }
            }
        })
        .build();
try {
    retryer.call(task);
} catch (ExecutionException e) {
    e.printStackTrace();
} catch (RetryException e) {
    e.printStackTrace();
} 

핵심 실행 논리 분석:
long startTime = System.nanoTime();
for (int attemptNumber = 1; ; attemptNumber++) {
    Attempt attempt;
    try {
        //     
        V result = attemptTimeLimiter.call(callable);
        attempt = new ResultAttempt(result, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));
    } catch (Throwable t) {
        //     
        attempt = new ExceptionAttempt(t, attemptNumber, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime));
    }
    //      
    for (RetryListener listener : listeners) {
        listener.onRetry(attempt);
    }
    //         
    if (!rejectionPredicate.apply(attempt)) {
        return attempt.get();
    }
    //         
    if (stopStrategy.shouldStop(attempt)) {
        throw new RetryException(attemptNumber, attempt);
    } else {
        //           
        long sleepTime = waitStrategy.computeSleepTime(attempt);
        try {
            blockStrategy.block(sleepTime);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RetryException(attemptNumber, attempt);
        }
    }
}

 도입 에 의존 하 다
<dependency>
      <groupId>com.github.rholdergroupId>
      <artifactId>guava-retryingartifactId>
      <version>2.0.0version>
dependency>
Attempt: 한 번 에 임 무 를 수행 합 니 다.AttemptTimeLimiter: 1 차 퀘 스 트 수행 시간 제한 (1 차 퀘 스 트 수행 시간 초과 시 현재 퀘 스 트 수행 중지);BlockStrategies: 퀘 스 트 차단 전략 (쉽게 말 하면 현재 퀘 스 트 가 완료 되 었 습 니 다. 다음 퀘 스 트 가 시작 되 지 않 았 을 때 무엇 을 합 니까?) 기본 전략 은: BlockStrategies.THREAD_SLEEP_STRATEGY 입 니 다. 호출  Thread.sleep(sleepTime) ; RetryException: 이상 을 다시 시도 합 니 다.RetryListener: 오류 로 그 를 비동기 로 기록 할 수 있 는 모니터 를 사용자 정의 합 니 다.StopStrategy: 재 시도 정책 을 중단 하고 세 가 지 를 제공 합 니 다.
  • StopAfterDelayStrategy  :가장 긴 실행 시간 설정 하기;예 를 들 어 최 장 10s 를 설정 하고 임무 수행 횟수 에 관 계 없 이 재 시도 할 때 최 장 시간 을 초과 하면 임무 가 종료 되 고 재 시도 이상 RetryException 을 되 돌려 줍 니 다.
  • NeverStopStrategy  :멈 추 지 않 고 기대 결과 로 돌아 가 는 상황 을 계속 훈련 해 야 한다.
  • StopAfterAttemptStrategy  :최대 재 시도 횟수 를 설정 하고 최대 재 시도 횟수 를 초과 하면 재 시도 가 중단 되 며 재 시도 이상 을 되 돌려 줍 니 다.
  • WaitStrategy: 대기 시간 정책 (제어 시간 간격), 다음 실행 시간 으로 되 돌아 갑 니 다.
  • FixedWaitStrategy: 고정 대기 시간 전략;
  • RandomWaitStrategy: 랜 덤 대기 시간 정책 (최소 시간 과 최대 시간 을 제공 할 수 있 고 대기 시간 은 구간 의 랜 덤 값)
  • IncrementingWaitStrategy: 대기 시간 증가 전략 (초기 값 과 걸음 길 이 를 제공 하고 대기 시간 은 재 시도 횟수 가 증가 함 에 따라 증가 합 니 다)
  • ExponentialWaitStrategy: 지수 대기 시간 전략;
  • FibonacciWaitStrategy  :Fibonacci 대기 시간 정책;
  • ExceptionWaitStrategy  :이상 시간 대기 정책;
  • CompositeWaitStrategy  :복합 시간 대기 정책;

  •  
    참고:
    http://blog.csdn.net/aitangyong/article/details/53894997
    https://segmentfault.com/a/1190000006918410
    http://blog.csdn.net/aitangyong/article/details/53886293
    http://baijiahao.baidu.com/s?id=1575327487081031&wfr=spider&for=pc
    http://www.cnblogs.com/jianzh5/p/6651799.html
    http://lintrip.com/2016/05/27/guava-retry/(상기 부분 내용 은 이 글 에서 전 환 됩 니 다)

    좋은 웹페이지 즐겨찾기