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

詳解如何在SpringBoot中優(yōu)雅地重試調(diào)用第三方API

 更新時(shí)間:2022年12月16日 13:57:31   作者:JAVA旭陽  
作為后端程序員,我們的日常工作就是調(diào)用一些第三方服務(wù),將數(shù)據(jù)存入數(shù)據(jù)庫,返回信息給前端。本文為大家介紹了如何在SpringBoot中優(yōu)雅地重試調(diào)用第三方API,需要的可以參考一下

前言

作為后端程序員,我們的日常工作就是調(diào)用一些第三方服務(wù),將數(shù)據(jù)存入數(shù)據(jù)庫,返回信息給前端。但你不能保證所有的事情一直都很順利。像有些第三方API,偶爾會(huì)出現(xiàn)超時(shí)。此時(shí),我們要重試幾次,這取決于你的重試策略。

下面舉一個(gè)我在日常開發(fā)中多次看到的例子:

public interface OutSource {
    List<Integer> getResult() throws TimeOutException;
}

@Service
public class OutSourceImpl implements OutSource {

    static Random random = new Random();
    @Override
    public List<Integer> getResult() {
        //mock failure
        if (random.nextInt(2) == 1)
            throw new TimeOutException();
        return List.of(1, 2, 3);
    }
}


@Slf4j
@Service
public class ManuallyRetryService {

    @Autowired
    private OutSource outSource;

    public List<Integer> getOutSourceResult(String data, int retryTimes) {
        log.info("trigger time:{}", retryTimes);

        if (retryTimes > 3) {
            return List.of();
        }

        try {
            List<Integer> lst = outSource.getResult();
            if (!CollectionUtils.isEmpty(lst)) {
                return lst;
            }

            log.error("getOutSourceResult error, data:{}", data);
        } catch (TimeOutException e) {
            log.error("getOutSourceResult timeout", e);
        }
        // 遞歸調(diào)用
        return getOutSourceResult(data, retryTimes + 1);
    }

}

@Slf4j
@RestController
public class RetryTestController {

    @Autowired
    private ManuallyRetryService manuallyRetryService;
    
    @GetMapping("manually")
    public String manuallyRetry() {
        List<Integer> result = manuallyRetryService.getOutSourceResult("haha", 0);
        if (!CollectionUtils.isEmpty(result)) {
            return "ok";
        }
        return "fail";
    }
}

看看上面這段代碼,我認(rèn)為它可以正常工作,當(dāng)retryTimes達(dá)到4時(shí),無論如何我們都會(huì)得到最終結(jié)果。但是你覺得寫的好嗎?優(yōu)雅嗎?下面我來介紹Spring中的一個(gè)組件:spring-retry,我們不妨來試一試。

Spring-Retry介紹使用

spring-retry是Spring中的提供的一個(gè)重試框架,提供了注解的方式,在不入侵原有業(yè)務(wù)邏輯代碼的方式下,優(yōu)雅的實(shí)現(xiàn)重處理功能。

安裝依賴

如果你的是gradle應(yīng)用,引入下面的依賴

implementation 'org.springframework.boot:spring-boot-starter-aop''org.springframework.boot:spring-boot-starter-aop'
implementation 'org.springframework.retry:spring-retry'

如果你的項(xiàng)目使用的是maven項(xiàng)目,引入下面的依賴

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

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

啟用重試功能

添加@EnableRetry注解在入口的類上從而啟用功能。

@SpringBootApplication
//看過來
@EnableRetry
public class TestSpringApplication {

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

}

應(yīng)用

我們以前面的為例,看看怎么使用,如下面的代碼:

public interface OutSource {
    List<Integer> getResult() throws TimeOutException;
}

@Service
public class OutSourceImpl implements OutSource {

    static Random random = new Random();
    @Override
    public List<Integer> getResult() {
        //mock failure will throw an exception every time
        throw new TimeOutException();
    }
}

@Slf4j
@Service
public class RetryableService {

    @Autowired
    private OutSource outSource;

    // 看這里
    @Retryable(value = {TimeOutException.class}, maxAttempts = 3)
    public List<Integer> getOutSourceResult(String data) {
        log.info("trigger timestamp:{}", System.currentTimeMillis() / 1000);

        List<Integer> lst = outSource.getResult();
        if (!CollectionUtils.isEmpty(lst)) {
            return lst;
        }
        log.error("getOutSourceResult error, data:{}", data);

        return null;
    }

}


@Slf4j
@RestController
public class RetryTestController {

    @Autowired
    private RetryableService retryableService;

    @GetMapping("retryable")
    public String manuallyRetry2() {
        try {
            List<Integer> result = retryableService.getOutSourceResult("aaaa");
            if (!CollectionUtils.isEmpty(result)) {
                return "ok";
            }
        } catch (Exception e) {
            log.error("retryable final exception", e);
        }
        return "fail";
    }

}

關(guān)鍵在于Service層中的實(shí)現(xiàn)類中添加了 @Retryable注解,實(shí)現(xiàn)了重試, 指定value是TimeOutException異常會(huì)進(jìn)行重試,最大重試maxAttempts3次。

驗(yàn)證

這一次,當(dāng)我們?cè)L問http://localhost:8080/retryable時(shí),我們將看到瀏覽器上的結(jié)果失敗。然后在你的終端上看到:

INFO 66776 --- [nio-9997-exec-1] c.m.testspring.service.RetryableService  : trigger timestamp:1668236840
 INFO 66776 --- [nio-9997-exec-1] c.m.testspring.service.RetryableService  : trigger timestamp:1668236841
 INFO 66776 --- [nio-9997-exec-1] c.m.testspring.service.RetryableService  : trigger timestamp:1668236842
ERROR 66776 --- [nio-9997-exec-1] c.m.t.controller.RetryTestController     : retryable final exception

總結(jié)

本文分享了spring-retry重試框架最基礎(chǔ)的使用,可以無侵入業(yè)務(wù)代碼進(jìn)行重試。關(guān)于spring-retry更多的使用建議可以自己去官網(wǎng)https://github.com/spring-projects/spring-retry 探索。

到此這篇關(guān)于詳解如何在SpringBoot中優(yōu)雅地重試調(diào)用第三方API的文章就介紹到這了,更多相關(guān)SpringBoot重試調(diào)用第三方API內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

太谷县| 南汇区| 青龙| 同德县| 临猗县| 贡山| 辛集市| 金秀| 贡山| 木兰县| 景泰县| 剑河县| 吉林市| 名山县| 井陉县| 保定市| 闸北区| 东平县| 九江县| 调兵山市| 琼中| 高雄县| 吕梁市| 武威市| 岚皋县| 金乡县| 大余县| 滦南县| 乐东| 马山县| 孙吴县| 嘉兴市| 中西区| 宁都县| 行唐县| 浦县| 商丘市| 山西省| 马尔康县| 黑河市| 南乐县|