【線上】再試行メカニズムを加える(guava-retryingを使用)


シーンを再試行する必要がある場合:
  • Druid.IOクラスタで境界状況
  • に遭遇する
    druidクラスタにはrunning taskがあり、running taskに対して対応するmiddlemanagerプロセスが実行する.druidはtask状態を表示するインタフェースとプロセス情報を表示するインタフェースを提供する.
    境界状況でクエリーが発生してtaskがrunningであるが、取得プロセス情報を呼び出すインタフェースが呼び出されない場合
  • druidクラスタの瞬間のpending taskは約1-2秒程度で大量のpending taskが出現するが,その後running状態の
  • となる.
    guava retryerの簡単な使用
    import com.github.rholder.retry.*;
    import com.google.common.base.Predicates;
    
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    class RsDto{
        public List<Integer> li;
    
        public RsDto() {
        }
    
        public RsDto(List<Integer> li) {
            this.li = li;
        }
    
        @Override
        public String toString() {
            return "RsDto{" +
                    "li=" + li +
                    '}';
        }
    }
    
    /**
     * @Author mubi
     * @Date 2019/3/26 11:21 PM
     */
    public class Main {
    
        private static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss,SSS");
    
        private static int cnt = 0;
    
        RsDto test(){
            cnt ++;
            try{
                System.out.println("cnt:" + cnt + ": " + df.format(new Date()));
    //            int a = 1 / 0;
            }catch (Exception e){
                e.printStackTrace();
    //            throw e;
            }
    //        return new Random().nextBoolean();
            if(cnt < 2){
                return null;
            }
            return new RsDto(Arrays.asList(1,2,3));
        }
    
        public static void main(String[] args){
            Main main = new Main();
            Callable<RsDto> sendTask = () -> main.test();
            Retryer<RsDto> retryer = RetryerBuilder.<RsDto>newBuilder()
                    //   Exception   
                    .retryIfException()
                    // return null   
                    .retryIfResult(Predicates.isNull())
                    .withWaitStrategy(WaitStrategies.incrementingWait(1, TimeUnit.SECONDS,2,TimeUnit.SECONDS))
                    .withStopStrategy(StopStrategies.stopAfterAttempt(4))
    //                .withAttemptTimeLimiter(AttemptTimeLimiters.>fixedTimeLimit(3,TimeUnit.SECONDS))
                    .withRetryListener(new RetryListener() {
                        @Override
                        public <RsDto> void onRetry(Attempt<RsDto> attempt) {
                            //      ,(  :             )
                            RsDto result = null;
                            System.out.print("[retry]time=" + attempt.getAttemptNumber());
                            if (attempt.hasException()){
                                attempt.getExceptionCause().printStackTrace();
                            }
                            try {
                                result = (RsDto) attempt.get();
                                System.out.println(",rude get=" + result);
                            } catch (ExecutionException e) {
                                System.err.println("this attempt produce exception." + e.getCause().toString());
                            }
                        }
                    })
                    .build();
            RsDto rs = null;
            try {
                rs = retryer.call(sendTask);
            } catch (ExecutionException e){
    //            e.printStackTrace();
                System.out.println("ExecutionException: " + rs);
            } catch (RetryException e1) {
    //            e1.printStackTrace();
                System.out.println("RetryException: " + rs);
            }
            System.out.println("main end rs:" + rs);
        }
    
    }