中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么進行Spring-Retry的使用

發布時間:2021-11-11 21:07:20 來源:億速云 閱讀:116 作者:柒染 欄目:開發技術

怎么進行Spring-Retry的使用,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

1 Spring-Retry的簡介

在日常的一些場景中, 很多需要進行重試的操作.而spring-retry是spring提供的一個基于spring的重試框架,非常簡單好用.

2 Spring中的應用

1 導入maven坐標

 <dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.2.RELEASE</version>
 </dependency>

2 添加被調用類

@Slf4j
public class RetryDemo {

    public static boolean retryMethod(Integer param) {
        int i = new Random().nextInt(param);
        log.info("隨機生成的數:{}", i);

        if (1 == i) {
            log.info("為1,返回true.");
            return true;
        } else if (i < 1) {
            log.info("小于1,拋出參數異常.");
            throw new IllegalArgumentException("參數異常");
        } else if (i > 1 && i < 10) {
            log.info("大于1,小于10,拋出參數異常.");
            return false;
        } else {
            //為其他
            log.info("大于10,拋出自定義異常.");
            throw new RemoteAccessException("大于10,拋出自定義異常");
        }
    }
}

3 添加測試類

@Slf4j
public class SpringRetryTest {

    /**
     * 重試間隔時間ms,默認1000ms
     */
    private long fixedPeriodTime = 1000L;
    /**
     * 最大重試次數,默認為3
     */
    private int maxRetryTimes = 3;
    /**
     * 表示哪些異常需要重試
     * key一定要為Throwable異常的子類    Class<? extends Throwable>
     * value為true表示需要重試
     */
    private Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>();


    @Test
    public void test() {

        // 1 添加異常的處理結果 true為需要重試 false為不需要重試
        exceptionMap.put(RemoteAccessException.class, true);

        // 2 構建重試模板實例
        RetryTemplate retryTemplate = new RetryTemplate();

        // 3 設置重試回退操作策略  設置重試間隔時間
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(fixedPeriodTime);

        // 4 設置重試策略  設置重試次數 設置異常處理結果
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(maxRetryTimes, exceptionMap);

        //5 重試模板添加重試策略 添加回退操作策略
        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);
    
        // 6 調用方法
        Boolean resp = retryTemplate.execute(
                // RetryCallback 重試回調方法
                retryContext -> {
                    boolean result = RetryDemo.retryMethod(110);
                    log.info("方法返回結果= {}", result);
                    return result;
                },
                // RecoveryCallback 異常回調方法
                retryContext -> {
                    //
                    log.info("超過最大重試次數或者拋出了未定義的異常!!!");
                    return false;
                }
        );

        log.info("接口返回結果 = {}",resp);

    }

}
/*
 // 查看結果
 [main] INFO com.cf.demo.SpringRetry.SpringRetryTest - 超過最大重試次數或者拋出了未定義的異常!!!
 [main] INFO com.cf.demo.SpringRetry.SpringRetryTest - 接口返回結果 = false
*/

從代碼的書寫注解可以看到,RetryTemplate對象是Spring-Retry框架的重試執行者, 由它添加重試策略,回退操作策略等(注釋第五步).RetryTemplate執行重試方法(注釋第六步),通過execute方法, 傳入的參數是重試回調邏輯對象RetryCallback 和執行操作結束的恢復對象RecoveryCallback. 且可以切換添加的異常種類, 得知,只有添加過相應的異常,才會觸發重試操作,否則直接調用RecoveryCallback對象方法.

RetryTemplate的部分源碼:

 /**
  * Keep executing the callback until it either succeeds or the policy dictates that we
  * stop, in which case the recovery callback will be executed.
  *
  * @see RetryOperations#execute(RetryCallback, RecoveryCallback)
  * @param retryCallback the {@link RetryCallback}
  * @param recoveryCallback the {@link RecoveryCallback}
  * @throws TerminatedRetryException if the retry has been manually terminated by a
  * listener.
  */
 @Override
 public final <T, E extends Throwable> T execute(RetryCallback<T, E> retryCallback,
   RecoveryCallback<T> recoveryCallback) throws E {
  return doExecute(retryCallback, recoveryCallback, null);
 }

RetryTemplate添加重試策略源碼:

 /**
  * Setter for {@link RetryPolicy}.
  *
  * @param retryPolicy the {@link RetryPolicy}
  */
 public void setRetryPolicy(RetryPolicy retryPolicy) {
  this.retryPolicy = retryPolicy;
 }

RetryPolicy接口的實現類:

AlwaysRetryPolicy:允許無限重試,直到成功,可能會導致死循環

CircuitBreakerRetryPolicy:有熔斷功能的重試策略,需設置3個參數openTimeout、resetTimeout和delegate

CompositeRetryPolicy:組合重試策略,有兩種組合方式,樂觀組合重試策略是指只要有一個策略允許即可以重試,
悲觀組合重試策略是指只要有一個策略不允許即可以重試,但不管哪種組合方式,組合中的每一個策略都會執行

ExceptionClassifierRetryPolicy:設置不同異常的重試策略,類似組合重試策略,區別在于這里只區分不同異常的重試

NeverRetryPolicy:只允許調用RetryCallback一次,不允許重試

SimpleRetryPolicy:固定次數重試策略,默認重試最大次數為3次,RetryTemplate默認使用的策略

TimeoutRetryPolicy:超時時間重試策略,默認超時時間為1秒,在指定的超時時間內允許重試

RetryTemplate添加回退策略源碼:

 /**
  * Setter for {@link BackOffPolicy}.
  *
  * @param backOffPolicy the {@link BackOffPolicy}
  */
 public void setBackOffPolicy(BackOffPolicy backOffPolicy) {
  this.backOffPolicy = backOffPolicy;
 }

BackOffPolicy的實現類:

ExponentialBackOffPolicy:指數退避策略,需設置參數sleeper、initialInterval、maxInterval和multiplier,initialInterval指定初始休眠時間,默認100毫秒,maxInterval指定最大休眠時間,默認30秒,multiplier指定乘數,即下一次休眠時間為當前休眠時間*multiplier

ExponentialRandomBackOffPolicy:隨機指數退避策略,引入隨機乘數可以實現隨機乘數回退

FixedBackOffPolicy:固定時間的退避策略,需設置參數sleeper和backOffPeriod,sleeper指定等待策略,默認是Thread.sleep,即線程休眠,backOffPeriod指定休眠時間,默認1秒

NoBackOffPolicy:無退避算法策略,每次重試時立即重試

UniformRandomBackOffPolicy:隨機時間退避策略,需設置sleeper、minBackOffPeriod和maxBackOffPeriod,該策略在[minBackOffPeriod,maxBackOffPeriod之間取一個隨機休眠時間,minBackOffPeriod默認500毫秒,maxBackOffPeriod默認1500毫秒

3 SpringBoot中的應用

1 導入maven坐標

 <dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.2.RELEASE</version>
 </dependency>

 <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.1</version>
 </dependency>

2 添加一個管理類

@Service
@Slf4j
public class SpringRetryDemo {


    /**
     * 重試所調用方法
     * @return
     */
    // delay=2000L表示延遲2秒 multiplier=2表示兩倍 即第一次重試2秒后,第二次重試4秒后,第三次重試8秒后
    @Retryable(value = {RemoteAccessException.class}, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 2))
    public boolean call(Integer param) {
        return RetryDemo.retryMethod(param);
    }

    /**
     * 超過最大重試次數或拋出沒有指定重試的異常
     * @param e
     * @param param
     * @return
     */
    @Recover
    public boolean recover(Exception e, Integer param) {
        log.info("請求參數為: ", param);
        log.info("超過最大重試次數或拋出沒有指定重試的異常, e = {} ", e.getMessage());
        return false;
    }
}

3 啟動類上添加注解@EnableRetry

@SpringBootApplication
@EnableRetry
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

4 添加測試類

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
@Slf4j
public class DemoApplicationTests {

    @Autowired
    private SpringRetryDemo springRetryDemo;

    @Test
    public void testRetry() {
        boolean result = springRetryDemo.call(110);
        log.info("方法返回結果為: {}", result);
    }
}
/* 運行結果:

    隨機生成的數:77
    大于10,拋出自定義異常.
    隨機生成的數:23
    大于10,拋出自定義異常.
    隨機生成的數:82
    大于10,拋出自定義異常.
    請求參數為: 
    超過最大重試次數或拋出沒有指定重試的異常, e = 大于10,拋出自定義異常 
    方法返回結果為: false
*/

注解說明:
@Enableretry注解,啟用重試功能(默認是否基于子類代理,默認是否, 即是基于Java接口代理)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableAspectJAutoProxy(proxyTargetClass = false)
@Import(RetryConfiguration.class)
@Documented
public @interface EnableRetry {

 /**
  * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
  * to standard Java interface-based proxies. The default is {@code false}.
  *
  * @return whether to proxy or not to proxy the class
  */
 boolean proxyTargetClass() default false;

}

@Retryable注解, 標記的方法發生異常時會重試

  • value  指定發生的異常進行重試

  • include  與value一樣,默認為空,當exclude同時為空時,所有異常都重試

  • exclude  指定異常不重試,默認為空,當include同時為空,所有異常都重試

  • maxAttemps  重試次數,默認3

  • backoff  重試補充機制  默認是@Backoff()注解

@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).
  * @return exception types 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()}.
  * @since 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.
  * @since 1.2
  */
 String exceptionExpression() default "";
}

@Backoff注解

  • delay  延遲多久后重試

  • multiplier  延遲的倍數

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(RetryConfiguration.class)
@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.
  * @since 1.2
  */
 String delayExpression() default "";

 /**
<<<<<<< HEAD
  * An expression evaluating to the maximum wait (in milliseconds) between retries.
  * If less than the {@link #delay()} then ignored.
=======
  * 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.
>>>>>>> Fix @Backoff JavaDocs - maxDelay
  * Overrides {@link #maxDelay()}
  *
  * @return the maximum delay between retries (default 0 = ignored)
  * @since 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)
  * @since 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;

}

@Recover注解

當重試達到規定的次數后,被注解標記的方法將被調用, 可以在此方法中進行日志的記錄等操作.(該方法的入參類型,返回值類型需要和重試方法保持一致)

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Import(RetryConfiguration.class)
@Documented
public @interface Recover {
}

關于怎么進行Spring-Retry的使用問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鹤山市| 都安| 永修县| 綦江县| 连城县| 宁安市| 长海县| 临猗县| 彰武县| 贡山| 济阳县| 丹东市| 宝坻区| 平舆县| 五河县| 南郑县| 寿宁县| 淮阳县| 噶尔县| 读书| 甘南县| 崇义县| 嵊州市| 梁山县| 开封市| 东乡县| 吉林省| 绥化市| 娱乐| 田东县| 内乡县| 长丰县| 石柱| 古蔺县| 连云港市| 泰宁县| 两当县| 开封市| 靖州| 仪征市| 紫金县|