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

溫馨提示×

溫馨提示×

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

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

Spring?Retry重試框架如何使用

發布時間:2022-10-31 09:39:07 來源:億速云 閱讀:182 作者:iii 欄目:開發技術

這篇“Spring Retry重試框架如何使用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Spring Retry重試框架如何使用”文章吧。

首先引入依賴

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.3.4</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.9.1</version>
</dependency>

使用方式有兩種:命令式和聲明式

命令式

/**
 * 命令式的方式使用Spring Retry
 */
@GetMapping("/hello")
public String hello(@RequestParam("code") Integer code) throws Throwable {
    RetryTemplate retryTemplate = RetryTemplate.builder()
            .maxAttempts(3)
            .fixedBackoff(1000)
            .retryOn(RemoteAccessException.class)
            .build();
    retryTemplate.registerListener(new MyRetryListener());

    String resp = retryTemplate.execute(new RetryCallback<String, Throwable>() {
        @Override
        public String doWithRetry(RetryContext context) throws Throwable {
            return helloService.hello(code);
        }
    });

    return resp;
}

定義一個RetryTemplate,然后調用execute方法,可配置項比較多,不一一列舉

真正使用的時候RetryTemplate可以定義成一個Bean,例如:

@Configuration
public class RetryConfig {
    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = RetryTemplate.builder()
                .maxAttempts(3)
                .fixedBackoff(1000)
                .withListener(new MyRetryListener())
                .retryOn(RemoteAccessException.class)
                .build();
        return retryTemplate;
    }
}

業務代碼:

/**
 * 命令式的方式使用Spring Retry
 */
@Override
public String hello(int code) {
    if (0 == code) {
        System.out.println("出錯了");
        throw new RemoteAccessException("出錯了");
    }
    System.out.println("處理完成");
    return "ok";
}

Spring?Retry重試框架如何使用

Spring?Retry重試框架如何使用

Spring?Retry重試框架如何使用

監聽器實現:

package com.example.retry.listener;

import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;

public class MyRetryListener implements RetryListener {
    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        System.out.println("open");
        return true;
    }

    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        System.out.println("close");
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        System.out.println("error");
    }
}

聲明式(注解方式)

/**
 * 注解的方式使用Spring Retry
 */
@Retryable(value = Exception.class, maxAttempts = 2, backoff = @Backoff(value = 1000, delay = 2000, multiplier = 0.5))
@Override
public String hi(int code) {
    System.out.println("方法被調用");
    int a = 1/code;
    return "ok";
}

@Recover
public String hiRecover(Exception ex, int code) {
    System.out.println("重試結束");
    return "asdf";
}

這里需要主要的幾點

  • @EnableRetry(proxyTargetClass = true/false)

  • @Retryable 修飾的方法必須是public的,而且不能是同一個類中調用

  • @Recover 修飾的方法簽名必須與@Retryable修飾的方法一樣,除了第一個參數外

/**
 * 注解的方式使用Spring Retry
 */
@GetMapping("/hi")
public String hi(@RequestParam("code") Integer code) {
    return helloService.hi(code);
}

Spring?Retry重試框架如何使用

Spring?Retry重試框架如何使用

Spring?Retry重試框架如何使用

Spring?Retry重試框架如何使用

1. 用法

聲明式

@Configuration
@EnableRetry
public class Application {

}

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public void service() {
        // ... do something
    }
    @Recover
    public void recover(RemoteAccessException e) {
       // ... panic
    }
}

命令式

RetryTemplate template = RetryTemplate.builder()
				.maxAttempts(3)
				.fixedBackoff(1000)
				.retryOn(RemoteAccessException.class)
				.build();

template.execute(ctx -> {
    // ... do something
});

2. RetryTemplate

為了自動重試,Spring Retry 提供了 RetryOperations 重試操作策略

public interface RetryOperations {

    <T> T execute(RetryCallback<T> retryCallback) throws Exception;

    <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback)
        throws Exception;

    <T> T execute(RetryCallback<T> retryCallback, RetryState retryState)
        throws Exception, ExhaustedRetryException;

    <T> T execute(RetryCallback<T> retryCallback, RecoveryCallback<T> recoveryCallback,
        RetryState retryState) throws Exception;

}

基本回調是一個簡單的接口,允許插入一些要重試的業務邏輯:

public interface RetryCallback<T> {

    T doWithRetry(RetryContext context) throws Throwable;

}

回調函數被嘗試,如果失敗(通過拋出異常),它將被重試,直到成功或實現決定中止。

RetryOperations最簡單的通用實現是RetryTemplate

RetryTemplate template = new RetryTemplate();

TimeoutRetryPolicy policy = new TimeoutRetryPolicy();
policy.setTimeout(30000L);

template.setRetryPolicy(policy);

Foo result = template.execute(new RetryCallback<Foo>() {

    public Foo doWithRetry(RetryContext context) {
        // Do stuff that might fail, e.g. webservice operation
        return result;
    }

});

從Spring Retry 1.3開始,RetryTemplate支持流式配置:

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();

3. RecoveryCallback

當重試耗盡時,RetryOperations可以將控制傳遞給不同的回調:RecoveryCallback。

Foo foo = template.execute(new RetryCallback<Foo>() {
    public Foo doWithRetry(RetryContext context) {
        // business logic here
    },
  new RecoveryCallback<Foo>() {
    Foo recover(RetryContext context) throws Exception {
          // recover logic here
    }
});

4. Listeners

public interface RetryListener {

    void open(RetryContext context, RetryCallback<T> callback);

    void onSuccess(RetryContext context, T result);

    void onError(RetryContext context, RetryCallback<T> callback, Throwable e);

    void close(RetryContext context, RetryCallback<T> callback, Throwable e);

}

在最簡單的情況下,open和close回調在整個重試之前和之后,onSuccess和onError應用于個別的RetryCallback調用,onSuccess方法在成功調用回調之后被調用。

5. 聲明式重試

有時,你希望在每次業務處理發生時都重試一些業務處理。這方面的典型例子是遠程服務調用。Spring Retry提供了一個AOP攔截器,它將方法調用封裝在RetryOperations實例中。RetryOperationsInterceptor執行被攔截的方法,并根據提供的RepeatTemplate中的RetryPolicy在失敗時重試。

你可以在 @Configuration 類上添加一個 @EnableRetry 注解,并且在你想要進行重試的方法(或者類)上添加 @Retryable 注解,還可以指定任意數量的重試監聽器。

@Configuration
@EnableRetry
public class Application {

    @Bean
    public Service service() {
        return new Service();
    }

    @Bean public RetryListener retryListener1() {
        return new RetryListener() {...}
    }

    @Bean public RetryListener retryListener2() {
        return new RetryListener() {...}
    }

}

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public service() {
        // ... do something
    }
}

可以使用 @Retryable 的屬性類控制 RetryPolicy 和 BackoffPolicy

@Service
class Service {
    @Retryable(maxAttempts=12, backoff=@Backoff(delay=100, maxDelay=500))
    public service() {
        // ... do something
    }
}

如果希望在重試用盡時采用替代代碼返回,則可以提供恢復方法。方法應該聲明在與@Retryable實例相同的類中,并標記為@Recover。返回類型必須匹配@Retryable方法。恢復方法的參數可以包括拋出的異常和(可選地)傳遞給原始可重試方法的參數(或者它們的部分列表,只要在需要的最后一個之前不省略任何參數)。

@Service
class Service {
    @Retryable(RemoteAccessException.class)
    public void service(String str1, String str2) {
        // ... do something
    }
    @Recover
    public void recover(RemoteAccessException e, String str1, String str2) {
       // ... error handling making use of original args if required
    }
}

若要解決可選擇用于恢復的多個方法之間的沖突,可以顯式指定恢復方法名稱。

@Service
class Service {
    @Retryable(recover = "service1Recover", value = RemoteAccessException.class)
    public void service1(String str1, String str2) {
        // ... do something
    }

    @Retryable(recover = "service2Recover", value = RemoteAccessException.class)
    public void service2(String str1, String str2) {
        // ... do something
    }

    @Recover
    public void service1Recover(RemoteAccessException e, String str1, String str2) {
        // ... error handling making use of original args if required
    }

    @Recover
    public void service2Recover(RemoteAccessException e, String str1, String str2) {
        // ... error handling making use of original args if required
    }
}

以上就是關于“Spring Retry重試框架如何使用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

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

AI

北海市| 鹤庆县| 成武县| 彰武县| 樟树市| 锡林浩特市| 平阴县| 富阳市| 清涧县| 惠安县| 左贡县| 云霄县| 江川县| 永安市| 望城县| 黔西| 大余县| 察隅县| 宁夏| 喜德县| 手游| 商城县| 神农架林区| 宁强县| 离岛区| 资阳市| 甘泉县| 炉霍县| 潢川县| 武邑县| 馆陶县| 邻水| 江津市| 林州市| 吕梁市| 合作市| 焦作市| 融水| 庐江县| 健康| 巴林右旗|