참고 링크
 
  1. 배경 및 목적
    1. 요즘 MSA 등의 형태로 서비스를 만들다보니 외부 API호출하는 경우가 많음(또는 AWS 서비스 호출)
    2. 네트웤 문제나 스로틀링 등의 문제로 가끔 실패가 발생하는 경우가 있음. 실패가 발생할 경우 재 처리가 필요하여 사용
 
 
 
예제 소스 (from AWS)
  •  지수 백오프의 기본 아이디어는 오류 응답이 연이어 나올 때마다 재시도 간 대기 시간을 점진적으로 늘린다는 것.
  • 최대 지연 간격과 최대 재시도 횟수를 구현해야 함. 최대 지연 시간 간격과 최대 재시도 횟수는 고정 값일 필요가 없으며, 수행 중인 작업과 다른 로컬 요인(예: 네트워크 지연 시간)을 기반으로 설정
java 버전의 재 시도 대기시간 구하는 메소드 샘플
* 참고로 jitter를 적용하는게 좋음(위 aws글 참고
Thread.sleep(RetryUtil.getRetrySleepTime(retryCnt, 2, 1000, 2000)); //대기처리

	
/**
* 재 시도시 대기시간(sleep) 구하기
*  - 지수 백오프 알고리즘 기반
*
* @param retryCount 요청하는 재시도 횟수
* @param increaseBase 증가 처리의 지수의 밑(ex. 2^4 에서 2)
* @param increaseMillis 매 재 요청마다 증가하는 시간(밀리시간초)
* @param maxWaitMillis 최대 대기시간(밀리시간초). 매 증가하는 대기 시간은 최대 대기시간을 넘을 수 없음
* @return
*/
public static long getRetrySleepTime(int retryCount, double increaseBase, long increaseMillis, long maxWaitMillis) {

    long waitTime = ((long)Math.pow(increaseBase, retryCount) * increaseMillis); //ex) ((long)Math.pow(2, retryCount) * 100L);  => 100, 200, 400, 800, 1600과 같이 증가함
    return Math.min(waitTime, maxWaitMillis); //두번째 argment은 최대 대기시간(밀리세컨드)
}



 
AWS 샘플 소스
public enum Results {
    SUCCESS,
    NOT_READY,
    THROTTLED,
    SERVER_ERROR
}
 
 
/*
* Performs an asynchronous operation, then polls for the result of the
* operation using an incremental delay.
*/
public static void doOperationAndWaitForResult() {
 
 
    try {
        // Do some asynchronous operation.
        long token = asyncOperation();
 
 
        int retries = 0;
        boolean retry = false;
 
 
        do {
            long waitTime = Math.min(getWaitTimeExp(retries), MAX_WAIT_INTERVAL);
 
 
            System.out.print(waitTime + "\n");
 
 
            // Wait for the result.
            Thread.sleep(waitTime);
 
 
            // Get the result of the asynchronous operation.
            Results result = getAsyncOperationResult(token);
 
 
            if (Results.SUCCESS == result) {
                retry = false;
            } else if (Results.NOT_READY == result) {
                retry = true;
            } else if (Results.THROTTLED == result) {
                retry = true;
            } else if (Results.SERVER_ERROR == result) {
                retry = true;
            }
            else {
                // Some other error occurred, so stop calling the API.
                retry = false;
            }
 
 
        } while (retry && (retries++ < MAX_RETRIES));
    }
 
 
    catch (Exception ex) {
    }
}
 
 
/*
* Returns the next wait interval, in milliseconds, using an exponential
* backoff algorithm.
*/
public static long getWaitTimeExp(int retryCount) {
 
 
    long waitTime = ((long) Math.pow(2, retryCount) * 100L);
 
 
    return waitTime;
}
 

 

+ Recent posts