Spring Retry重試機(jī)制

在調(diào)用第三方接口或者使用mq時(shí),會(huì)出現(xiàn)網(wǎng)絡(luò)抖動(dòng),連接超時(shí)等網(wǎng)絡(luò)異常,所以需要重試。為了使處理更加健壯并且不太容易出現(xiàn)故障,后續(xù)的嘗試操作,有時(shí)候會(huì)幫助失敗的操作最后執(zhí)行成功。例如,由于網(wǎng)絡(luò)故障或數(shù)據(jù)庫更新中的DeadLockLoserException導(dǎo)致Web服務(wù)或RMI服務(wù)的遠(yuǎn)程調(diào)用可能會(huì)在短暫等待后自行解決。 為了自動(dòng)執(zhí)行這些操作的重試,Spring Batch具有RetryOperations策略。不過該重試功能從Spring Batch 2.2.0版本中獨(dú)立出來,變成了Spring Retry模塊。

引入依賴

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>

需要引入Spring-retry和aspectjweaver的依賴。

入口類


@SpringBootApplication
@EnableRetry
public class SpringbootRetryApplication {

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

入口類上開啟retry的攔截,使用@EnableRetry注解。

Service

@Service
public class PayService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private final int totalNum = 100000;

    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
    public int minGoodsnum(int num) throws Exception {
        logger.info("減庫存開始" + LocalTime.now());
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            logger.error("illegal");
        }
        if (num <= 0) {
            throw new IllegalArgumentException("數(shù)量不對(duì)");
        }
        logger.info("減庫存執(zhí)行結(jié)束" + LocalTime.now());
        return totalNum - num;
    }
}

@Retryable的參數(shù)說明:

  • value:拋出指定異常才會(huì)重試
  • include:和value一樣,默認(rèn)為空,當(dāng)exclude也為空時(shí),默認(rèn)所以異常
  • exclude:指定不處理的異常
  • maxAttempts:最大重試次數(shù),默認(rèn)3次
  • backoff:重試等待策略,默認(rèn)使用@Backoff,@Backoff的value默認(rèn)為1000L,我們?cè)O(shè)置為2000L;multiplier(指定延遲倍數(shù))默認(rèn)為0,表示固定暫停1秒后進(jìn)行重試,如果把multiplier設(shè)置為1.5,則第一次重試為2秒,第二次為3秒,第三次為4.5秒。

測(cè)試類

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRetryApplicationTests {
    @Autowired
    private PayService payService;

    @Test
    public void payTest() throws Exception {
        int store = payService.minGoodsnum(-1);
        System.out.println("庫存為:" + store);
    }

}

運(yùn)行的控制臺(tái)結(jié)果如下:

image

可以看到,三次之后拋出了IllegalArgumentException異常。

當(dāng)重試耗盡時(shí),RetryOperations可以將控制傳遞給另一個(gè)回調(diào),即RecoveryCallback。Spring-Retry還提供了@Recover注解,用于@Retryable重試失敗后處理方法,此方法里的異常一定要是@Retryable方法里拋出的異常,否則不會(huì)調(diào)用這個(gè)方法。

@Recover
public int recover(Exception e) {
    logger.warn("減庫存失?。。?!" + LocalTime.now());
    return totalNum;
}

在Service中,加上如上的方法之后,進(jìn)行測(cè)試。


image

可以看到當(dāng)三次重試執(zhí)行完之后,會(huì)調(diào)用Recovery方法,也不會(huì)再次拋出異常。

總結(jié)

本文主要講了在Spring Boot項(xiàng)目中的Spring-Retry簡(jiǎn)單應(yīng)用,主要是基于注解配置一些重試的策略,使用比較簡(jiǎn)單。主要的適用場(chǎng)景為在調(diào)用第三方接口或者使用mq時(shí)。由于會(huì)出現(xiàn)網(wǎng)絡(luò)抖動(dòng),連接超時(shí)等網(wǎng)絡(luò)異常,這時(shí)就需要重試。

本文的代碼: https://github.com/keets2012/Spring-Cloud_Samples/tree/master/springboot-retry

訂閱最新文章,歡迎關(guān)注我的公眾號(hào)

微信公眾號(hào)

參考

  1. springboot 整合retry(重試機(jī)制)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • 準(zhǔn)備好好看看一下spring-cloud的源碼,把其中實(shí)現(xiàn)的原理搞清楚,而不是僅僅會(huì)配幾個(gè)注解,會(huì)配幾個(gè)參數(shù),把“...
    沉寂之舟閱讀 14,926評(píng)論 0 6
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,273評(píng)論 6 342
  • 多情總被薄情負(fù)。
    Zy的記事本閱讀 365評(píng)論 0 0
  • 外部命令vim + abc打開abc,光標(biāo)在最后一行vim +/search filename定位到search第...
    一言不合拔蘿卜閱讀 242評(píng)論 0 0

友情鏈接更多精彩內(nèi)容