最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring Retryable注解實現(xiàn)重試詳解

 更新時間:2020年09月18日 10:42:36   作者:會灰翔的灰機  
這篇文章主要介紹了spring Retryable注解實現(xiàn)重試詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

spring-boot:1.5.3.RELEASE,spring-retry-1.2.0.RELEASE

使用方法

引入pom

// 版本號繼承spring-boot依賴管理的pom
<dependency>
 <groupId>org.springframework.retry</groupId>
 <artifactId>spring-retry</artifactId>
</dependency>
<dependency>
 <groupId>org.aspectj</groupId>
 <artifactId>aspectjweaver</artifactId>
</dependency>

啟用重試

@Configuration
@ImportResource(locations = { "classpath*:spring/app-context-*" })
@EnableRetry
public class AppContext {
}

注解需要重試的方法

@Retryable(value = RuntimeException.class, maxAttempts = 3,backoff = @Backoff(delay = 10L, multiplier = 1))
public boolean myRetryableMethod(){
  ...
}

注解屬性含義

Retryable

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Retryable {

 /**
 * 為重試方法應用重試攔截器的bean名稱。與其他屬性互斥
 */
 String interceptor() default "";

 /**
 * 可以重試的異常類型。與includes屬性同義。默認值為空(并且如果exclude也是空的話,
   * 所有的異常都會重試)
 */
 Class<? extends Throwable>[] value() default {};

 /**
 * 同上
 */
 Class<? extends Throwable>[] include() default {};

 /**
 * 與include含義相反
 */
 Class<? extends Throwable>[] exclude() default {};

 /**
 * 統(tǒng)計報告的唯一標簽。如果沒有提供,調用者可以選擇忽略它,或者提供一個默認值。
 *
 * @return the label for the statistics
 */
 String label() default "";

 /**
 * 標識重試有狀態(tài)的:即異常重新拋出,但是重試策略使用相同的策略應用于后續(xù)的具有相同參數(shù)的
   * 調用。如果為false那么可重試的異常不會重新拋出。
 */
 boolean stateful() default false;

 /**
   * 嘗試的最大次數(shù)(包含第一次失敗),默認為3
 */
 int maxAttempts() default 3;

 /**
 * 返回一個求嘗試最大次數(shù)值的表達式(包含第一次失敗),默認為3
   * 重寫 {@link #maxAttempts()}。
 * @since 1.2
 */
 String maxAttemptsExpression() default "";

 /**
 * 為正重試的動作指定backoff屬性。默認沒有backoff,但是在兩次嘗試之間暫定一下是一個很好的想法
 * (即使代價是阻塞線程)
 */
 Backoff backoff() default @Backoff();

 /**
 * 在{@code SimpleRetryPolicy.canRetry()}返回true之后指定一個計算表達式 - 可用來有條件的取消重試。
 * 僅在調用拋出一個異常后。求值的root對象為上一次的異常 {@code Throwable}。
 * 可以引用上下文中的其他beans。
 * 例如:
 * {@code "message.contains('you can retry this')"}.
 * and
 * {@code "@someBean.shouldRetry(#root)"}.
 * @since 1.2
 */
 String exceptionExpression() default "";
}

Backoff

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(RetryConfiguration.class)
@Documented
public @interface Backoff {

 /**
 * 與 {@link #delay()} 屬性同義
 *
 * 返回延遲多少毫秒后重試(默認為1000毫秒)
 */
 long value() default 1000;

 /**
 * 一個標準的再重試周期。在指數(shù)函數(shù)情況下用作初始值,在始終如一的情況下(固定周期值情況)
 * 用作最小值。
 * @return the initial or canonical backoff period in milliseconds (default 1000)???
 */
 long delay() default 0;

 /**
 * 重試之間最大等待(毫秒)時間。如果小于 {@link #delay()} 則忽略。
 * @return the maximum delay between retries (default 0 = ignored)
 */
 long maxDelay() default 0;

 /**
 * 如果是正數(shù),則用于生成下次再重試等待時間的乘數(shù)。
 * 返回一個乘數(shù)用于計算下次再重試延遲(默認為0忽略)
 */
 double multiplier() default 0;

 /**
 * 標準再重試周期求值表達式。在指數(shù)情況下用作初始值,始終如一的情況下用作最小值。
 * 重寫 {@link #delay()}.
 * @since 1.2
 */
 String delayExpression() default "";

 /**
 * 在重試之間最大等待(毫秒)數(shù)的求值表達式。
 * 如果小于 {@link #delay()} 則忽略。
 * 重寫 {@link #maxDelay()}
 * 默認為0,忽略
 * @since 1.2
 */
 String maxDelayExpression() default "";

 /**
 * 表達式求值作為生成下次再重試延遲的乘數(shù)
 * 重寫 {@link #multiplier()}。
 * @since 1.2
 */
 String multiplierExpression() default "";

 /**
 * 在指數(shù)情況下 ({@link #multiplier()} > 0) 設置該值為true將使再重試延遲隨機化,
 * 使最大延遲為先前延遲的乘數(shù)倍數(shù),并使這兩個延遲值之間分布均勻。
 * 默認為false
 */
 boolean random() default false;
}

案例

默認retry

@Component
public class MyTask {

  @Retryable
  public void doExecute(){
    System.out.println("## current Date:" + new Date());
    throw new RuntimeException("my test");
  }
}

輸出結果

## current Date:Sat Aug 29 21:54:55 CST 2020 ## current Date:Sat Aug 29 21:54:56 CST 2020 ## current Date:Sat Aug 29 21:54:57 CST 2020 2020-08-29 21:55:00,319 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread "main" java.lang.RuntimeException: my test ...

stateful

源碼相同,注解增加屬性配置

@Retryable( stateful = true )

public void doExecute(){

輸出結果

## current Date:Sat Aug 29 21:58:56 CST 2020 2020-08-29 21:58:57,557 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread "main" java.lang.RuntimeException: my test // 沒有重新拋出異常觸發(fā)重試

該參數(shù)為false時會重試3次后拋出異常,重試期間不會重新拋出異常。參數(shù)為true時則重試期間也會重新拋出異常導致重試失敗不再繼續(xù)重試

backoff.multiplier

注解屬性配置

@Retryable( backoff = @Backoff( delay = 1000, multiplier = 2), maxAttempts = 10)

輸出結果

## current Date:Sat Aug 29 23:06:50 CST 2020 ## current Date:Sat Aug 29 23:06:51 CST 2020 ## current Date:Sat Aug 29 23:06:53 CST 2020 ## current Date:Sat Aug 29 23:06:57 CST 2020 ## current Date:Sat Aug 29 23:07:05 CST 2020 ## current Date:Sat Aug 29 23:07:21 CST 2020 ## current Date:Sat Aug 29 23:07:51 CST 2020 ## current Date:Sat Aug 29 23:08:21 CST 2020 ## current Date:Sat Aug 29 23:08:51 CST 2020 ## current Date:Sat Aug 29 23:09:21 CST 2020 2020-08-29 23:09:21,949 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread "main" java.lang.RuntimeException: my test

乘數(shù)正確,指數(shù)型增長,第1次延遲1s

第2次,上次延遲1s乘以乘數(shù)2=延遲2s

第3次,上次延遲2s乘以乘數(shù)2=延遲4s

指數(shù)增長,如果沒有指定則為始終如一的固定間隔延遲類型。新版本已經增加了各種類型單獨的屬性配置的模板構建者:

RetryTemplate.builder()
   .maxAttempts(10)
   .exponentialBackoff(100, 2, 10000)
   .retryOn(IOException.class)
   .traversingCauses()
   .build();

RetryTemplate.builder()
   .fixedBackoff(10)
   .withinMillis(3000)
   .build();

RetryTemplate.builder()
   .infiniteRetry()
   .retryOn(IOException.class)
   .uniformRandomBackoff(1000, 3000)
   .build();

backoff.random

測試代碼

@Component
public class MyTask {

  private Long lastTime = null;

  @Retryable( backoff = @Backoff( delay = 1000, multiplier = 2, random = true), maxAttempts = 10)
  public void doExecute(){
    if (lastTime == null) {
      lastTime = System.currentTimeMillis();
    }
    System.out.println("## actual delay:" + (System.currentTimeMillis() - lastTime) );
    RuntimeException runtimeException = new RuntimeException("my test");
    throw runtimeException;
  }
}

輸出結果

## current Date:Sat Aug 29 22:53:10 CST 2020
## current Date:Sat Aug 29 22:53:11 CST 2020
## current Date:Sat Aug 29 22:53:14 CST 2020
## current Date:Sat Aug 29 22:53:20 CST 2020
## current Date:Sat Aug 29 22:53:29 CST 2020
## current Date:Sat Aug 29 22:53:51 CST 2020
## current Date:Sat Aug 29 22:54:41 CST 2020
## current Date:Sat Aug 29 22:55:25 CST 2020
## current Date:Sat Aug 29 22:56:11 CST 2020
## current Date:Sat Aug 29 22:57:01 CST 2020
2020-08-29 22:57:01,617 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection
Exception in thread "main" java.lang.RuntimeException: my test

延遲更加隨機化,由于是最大延遲為之前延遲的乘數(shù)的倍數(shù),所以看不出規(guī)律。它的使用場景是使延遲更加隨機化

exceptionExpression

測試代碼

@Component
public class MyTask {

  private Long lastTime = null;

  public boolean canRetry(RuntimeException runtimeException) {
    System.out.println("canRetry:"+runtimeException.hashCode());
    return true;
  }

  @Retryable(exceptionExpression = "#{@myTask.canRetry(#root)}", backoff = @Backoff(delay = 1000, multiplier = 2, random = true))
  public void doExecute() {
    if (lastTime == null) {
      lastTime = System.currentTimeMillis();
    }
    System.out.println("## actual delay:" + (System.currentTimeMillis() - lastTime));
    RuntimeException runtimeException = new RuntimeException("my test");
    System.out.println("doExecute:"+runtimeException.hashCode());
    throw runtimeException;
  }
}

輸出結果

## actual delay:0 doExecute:626562869 2020-08-29 23:50:49,905 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:626562869 2020-08-29 23:50:49,906 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection 2020-08-29 23:50:51,335 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:626562869 2020-08-29 23:50:51,336 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection ## actual delay:1450 doExecute:90418597 2020-08-29 23:50:51,337 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:90418597 2020-08-29 23:50:51,338 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection 2020-08-29 23:50:53,620 DEBUG [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:28 public boolean com.dianwoda.billing.settle.task.MyTask.canRetry(java.lang.RuntimeException) execute with datasource is master canRetry:90418597 2020-08-29 23:50:53,620 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection ## actual delay:3734 doExecute:307531674 2020-08-29 23:50:53,621 INFO [main] com.dianwoba.common.datasource.DataSourceAspect:invoke:32 restore database connection Exception in thread "main" java.lang.RuntimeException: my test

注意:1.2.5之后表達式的預發(fā)有所改變,詳情可以參考官方文檔:https://github.com/spring-projects/spring-retry

以上這篇spring Retryable注解實現(xiàn)重試詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Mybatis-Plus-AutoGenerator 最詳細使用方法

    Mybatis-Plus-AutoGenerator 最詳細使用方法

    這篇文章主要介紹了Mybatis-Plus-AutoGenerator 最詳細使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • Java+MySQL實現(xiàn)設計優(yōu)惠券系統(tǒng)

    Java+MySQL實現(xiàn)設計優(yōu)惠券系統(tǒng)

    這篇文章主要介紹了Java+MySQL實現(xiàn)設計優(yōu)惠券系統(tǒng),文章基于Java與MySQL的相關資料展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • Java基礎之讓你徹底搞懂代理模式

    Java基礎之讓你徹底搞懂代理模式

    這篇文章主要介紹了Java基礎之讓你徹底搞懂代理模式,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • 利用Java編寫一個Java虛擬機

    利用Java編寫一個Java虛擬機

    這篇文章主要為大家詳細介紹了如何使用 Java17 編寫的 Java 虛擬機,文中的示例代碼講解詳細,具有一定的學習價值,感興趣的可以了解下
    2023-07-07
  • 淺談springboot中tk.mapper代碼生成器的用法說明

    淺談springboot中tk.mapper代碼生成器的用法說明

    這篇文章主要介紹了淺談springboot中tk.mapper代碼生成器的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • jdk11?jdk17多版本共存切換方式

    jdk11?jdk17多版本共存切換方式

    這篇文章主要介紹了jdk11?jdk17多版本共存切換方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Java程序員面試中的多線程問題總結

    Java程序員面試中的多線程問題總結

    這篇文章收集了 Java 線程方面一些典型的問題,這些問題經常被高級工程師所問到。這篇文章收集了 Java 線程方面一些典型的問題,這些問題經常被高級工程師所問到。
    2016-11-11
  • springboot整合netty框架實現(xiàn)站內信

    springboot整合netty框架實現(xiàn)站內信

    Netty 是一個基于NIO的客戶、服務器端編程框架,使用Netty 可以確保你快速和簡單的開發(fā)出一個網(wǎng)絡應用,這篇文章主要介紹了springboot整合netty框架的方式小結,需要的朋友可以參考下
    2022-12-12
  • Java 二分法檢索算法代碼實現(xiàn)詳解

    Java 二分法檢索算法代碼實現(xiàn)詳解

    這篇文章主要介紹了Java 二分法檢索算法代碼實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • 如何解決mybatis查詢結果接收不同的問題

    如何解決mybatis查詢結果接收不同的問題

    這篇文章主要介紹了如何解決mybatis查詢結果接收不同的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09

最新評論

洱源县| 武城县| 永修县| 台湾省| 东方市| 静安区| 新安县| 新宁县| 南充市| 万宁市| 长沙县| 万年县| 双流县| 建德市| 惠来县| 闽清县| 沅江市| 江口县| 大港区| 和田市| 水城县| 鸡泽县| 浦城县| 简阳市| 玉树县| 东乌珠穆沁旗| 永寿县| 布尔津县| 德州市| 龙州县| 安康市| 宣武区| 晋城| 获嘉县| 昌邑市| 金秀| 白水县| 如东县| 桃园市| 石棉县| 灌阳县|