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

SpringBoot @Retryable注解方式

 更新時(shí)間:2020年09月18日 10:16:16   作者:wtopps  
這篇文章主要介紹了SpringBoot @Retryable注解方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

背景

在調(diào)用第三方接口或者使用MQ時(shí),會(huì)出現(xiàn)網(wǎng)絡(luò)抖動(dòng),連接超時(shí)等網(wǎng)絡(luò)異常,所以需要重試。為了使處理更加健壯并且不太容易出現(xiàn)故障,后續(xù)的嘗試操作,有時(shí)候會(huì)幫助失敗的操作最后執(zhí)行成功。一般情況下,需要我們自行實(shí)現(xiàn)重試機(jī)制,一般是在業(yè)務(wù)代碼中加入一層循環(huán),如果失敗后,再嘗試重試,但是這樣實(shí)現(xiàn)并不優(yōu)雅。在SpringBoot中,已經(jīng)實(shí)現(xiàn)了相關(guān)的能力,通過(guò)@Retryable注解可以實(shí)現(xiàn)我們想要的結(jié)果。

@Retryable

首先來(lái)看一下Spring官方文檔的解釋:

@Retryable注解可以注解于方法上,來(lái)實(shí)現(xiàn)方法的重試機(jī)制。

POM依賴

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

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

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

使用實(shí)例

SpringBoot retry的機(jī)制比較簡(jiǎn)單,只需要兩個(gè)注解即可實(shí)現(xiàn)。

啟動(dòng)類

@SpringBootApplication
@EnableRetry
public class Application {
 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }
}

在啟動(dòng)類上,需要加入@EnableRetry注解,來(lái)開啟重試機(jī)制。

Service類

前面提到過(guò),@Retryable是基于方法級(jí)別的,因此在Service中,需要在你希望重試的方法上,增加重試注解。

@Service
@Slf4j
public class DoRetryService {

 @Retryable(value = Exception.class, maxAttempts = 4, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
 public boolean doRetry(boolean isRetry) throws Exception {
  log.info("開始通知下游系統(tǒng)");
  log.info("通知下游系統(tǒng)");
  if (isRetry) {
   throw new RuntimeException("通知下游系統(tǒng)異常");
  }
  return true;
 }
}

來(lái)簡(jiǎn)單解釋一下注解中幾個(gè)參數(shù)的含義:

名稱 含義
interceptor Retry interceptor bean name to be applied for retryable method.
value Exception types that are retryable. Synonym for includes(). Defaults to empty (and if excludes is also empty all exceptions are retried).
include Exception types that are retryable. Defaults to empty (and if excludes is also empty all exceptions are retried).
exclude Exception types that are not retryable. Defaults to empty (and if includes is also empty all exceptions are retried).
label A unique label for statistics reporting. If not provided the caller may choose to ignore it, or provide a default.
stateful 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.
maxAttempts the maximum number of attempts (including the first failure), defaults to 3
maxAttemptsExpression an expression evaluated to the maximum number of attempts (including the first failure), defaults to 3
backoff Specify the backoff properties for retrying this operation. The default is a simple specification with no properties.
exceptionExpression Specify an expression to be evaluated after the SimpleRetryPolicy.canRetry() returns true - can be used to conditionally suppress the retry.
listeners Bean names of retry listeners to use instead of default ones defined in Spring context.

上面是@Retryable的參數(shù)列表,參數(shù)較多,這里就選擇幾個(gè)主要的來(lái)說(shuō)明一下:

interceptor:可以通過(guò)該參數(shù),指定方法攔截器的bean名稱

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秒。

我們把上面的例子執(zhí)行一下,來(lái)看看效果:

2019-12-25 11:38:02.492 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統(tǒng)
2019-12-25 11:38:02.493 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統(tǒng)
2019-12-25 11:38:04.494 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統(tǒng)
2019-12-25 11:38:04.495 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統(tǒng)
2019-12-25 11:38:07.496 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統(tǒng)
2019-12-25 11:38:07.496 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統(tǒng)
2019-12-25 11:38:11.997 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統(tǒng)
2019-12-25 11:38:11.997 INFO 25664 --- [   main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統(tǒng)

java.lang.RuntimeException: 通知下游系統(tǒng)異常
...
...
...

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

@Recover

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

@Recover

public boolean doRecover(Throwable e, boolean isRetry) throws ArithmeticException {
 log.info("全部重試失敗,執(zhí)行doRecover");
 return false;
}

對(duì)于@Recover注解的方法,需要特別注意的是:

1、方法的返回值必須與@Retryable方法一致

2、方法的第一個(gè)參數(shù),必須是Throwable類型的,建議是與@Retryable配置的異常一致,其他的參數(shù),需要與@Retryable方法的參數(shù)一致

/**
 * Annotation for a method invocation that is a recovery handler. A suitable recovery
 * handler has a first parameter of type Throwable (or a subtype of Throwable) and a
 * return value of the same type as the <code>@Retryable</code> method to recover from.
 * The Throwable first argument is optional (but a method without it will only be called
 * if no others match). Subsequent arguments are populated from the argument list of the
 * failed method in order.
 */

@Recover不生效的問(wèn)題

在測(cè)試過(guò)程中,發(fā)現(xiàn)@Recover無(wú)法生效,執(zhí)行時(shí)拋出異常信息:

org.springframework.retry.ExhaustedRetryException: Cannot locate recovery method; nested exception is java.lang.ArithmeticException: / by zero

at org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler.recover(RecoverAnnotationRecoveryHandler.java:61)
at org.springframework.retry.interceptor.RetryOperationsInterceptor$ItemRecovererCallback.recover(RetryOperationsInterceptor.java:141)
at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:512)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:351)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180)
at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:115)
at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.invoke(AnnotationAwareRetryOperationsInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy157.doRetry(Unknown Source)

追蹤一下異常的信息,進(jìn)入到RecoverAnnotationRecoveryHandler中,找到報(bào)錯(cuò)的方法public T recover(Object[] args, Throwable cause),看一下其實(shí)現(xiàn):

發(fā)現(xiàn)報(bào)錯(cuò)處,是因?yàn)閙ethod為空而導(dǎo)致的,明明我已經(jīng)在需要執(zhí)行的方法上注解了@Recover,為什么還會(huì)找不到方法呢?很奇怪,再來(lái)深入追蹤一下:

打斷點(diǎn)到這,發(fā)現(xiàn)methods列表是空的,那么methods列表是什么時(shí)候初始化的呢?繼續(xù)追蹤:

發(fā)現(xiàn)了初始化methods列表的地方,這里會(huì)掃描注解了@Recover注解的方法,將其加入到methds列表中,那么為什么沒有掃描到我們注解了的方法呢?

很奇怪,為什么明明注解了@Recover,這里卻沒有掃描到呢?

我有點(diǎn)懷疑Spring掃描的部分,可能有什么問(wèn)題了,回頭去看看@EnableRetry是怎么說(shuō)的:

終于找到問(wèn)題的所在了,對(duì)于@EnableRetry中的proxyTargetClass參數(shù),是控制是否對(duì)使用接口實(shí)現(xiàn)的bean開啟代理類,默認(rèn)的情況下,是不開啟的,問(wèn)題原因就是這個(gè),我們來(lái)實(shí)驗(yàn)一下,把這個(gè)參數(shù)改成true:

@EnableRetry(proxyTargetClass = true)

再次運(yùn)行,果然沒有問(wèn)題了。

由此得出結(jié)論,當(dāng)使用接口實(shí)現(xiàn)的bean時(shí),需要將EnableRetry的參數(shù)改為true,非接口的實(shí)現(xiàn),可以使用默認(rèn)配置,即false。

結(jié)語(yǔ)

本篇主要簡(jiǎn)單介紹了Springboot中的Retryable的使用,主要的適用場(chǎng)景為在調(diào)用第三方接口或者使用MQ時(shí)。由于會(huì)出現(xiàn)網(wǎng)絡(luò)抖動(dòng),連接超時(shí)等網(wǎng)絡(luò)異常。

以上這篇SpringBoot @Retryable注解方式就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一篇文章弄懂JVM類加載機(jī)制過(guò)程以及原理

    一篇文章弄懂JVM類加載機(jī)制過(guò)程以及原理

    JVM原理對(duì)于初學(xué)者而言,比較晦澀難以理解,概念繁多又比較抽象,很多時(shí)候感覺看不見摸不著,還不好驗(yàn)證,下面這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章弄懂JVM類加載機(jī)制過(guò)程及原理的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • spring boot 中設(shè)置默認(rèn)網(wǎng)頁(yè)的方法

    spring boot 中設(shè)置默認(rèn)網(wǎng)頁(yè)的方法

    這篇文章主要介紹了spring boot 中設(shè)置默認(rèn)網(wǎng)頁(yè)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • 使用SpringAOP實(shí)現(xiàn)公共字段填充功能

    使用SpringAOP實(shí)現(xiàn)公共字段填充功能

    在新增員工或者新增菜品分類時(shí)需要設(shè)置創(chuàng)建時(shí)間、創(chuàng)建人、修改時(shí)間、修改人等字段,在編輯員工或者編輯菜品分類時(shí)需要設(shè)置修改時(shí)間、修改人等字段,這些字段屬于公共字段,本文將給大家介紹使用SpringAOP實(shí)現(xiàn)公共字段填充功能,需要的朋友可以參考下
    2024-08-08
  • SpringBoot的ConfigurationProperties或Value注解無(wú)效問(wèn)題及解決

    SpringBoot的ConfigurationProperties或Value注解無(wú)效問(wèn)題及解決

    在SpringBoot項(xiàng)目開發(fā)中,全局靜態(tài)配置類讀取application.yml或application.properties文件時(shí),可能會(huì)遇到配置值始終為null的問(wèn)題,這通常是因?yàn)樵趧?chuàng)建靜態(tài)屬性后,IDE自動(dòng)生成的Get/Set方法包含了static關(guān)鍵字
    2024-11-11
  • vue3使用vue-diff工具來(lái)比較數(shù)據(jù)差異

    vue3使用vue-diff工具來(lái)比較數(shù)據(jù)差異

    這篇文章主要為大家詳細(xì)介紹了vue3如何使用vue-diff工具來(lái)比較數(shù)據(jù)差異,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11
  • spring boot動(dòng)態(tài)切換數(shù)據(jù)源的實(shí)現(xiàn)

    spring boot動(dòng)態(tài)切換數(shù)據(jù)源的實(shí)現(xiàn)

    這篇文章主要介紹了spring boot動(dòng)態(tài)切換數(shù)據(jù)源的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java后臺(tái)接收數(shù)據(jù)的三種方式(url、form-data與application/json)

    Java后臺(tái)接收數(shù)據(jù)的三種方式(url、form-data與application/json)

    本文主要介紹了Java后臺(tái)接收數(shù)據(jù)的三種方式(url、form-data與application/json),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Java基礎(chǔ)詳解之內(nèi)存泄漏

    Java基礎(chǔ)詳解之內(nèi)存泄漏

    這篇文章主要介紹了Java基礎(chǔ)詳解之內(nèi)存泄漏,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-04-04
  • map實(shí)現(xiàn)按value升序排序

    map實(shí)現(xiàn)按value升序排序

    map內(nèi)部是按照hash算法存儲(chǔ)的,但如果能對(duì)map排序在某些時(shí)候還是有用的,下面實(shí)現(xiàn)對(duì)map按照value升序排序,實(shí)現(xiàn)對(duì)map按照key排序,大家參考使用吧
    2014-01-01
  • SpringBoot AOP注解失效問(wèn)題排查與解決(調(diào)用內(nèi)部方法)

    SpringBoot AOP注解失效問(wèn)題排查與解決(調(diào)用內(nèi)部方法)

    這篇文章主要介紹了SpringBoot AOP注解失效問(wèn)題排查與解決(調(diào)用內(nèi)部方法),文中通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04

最新評(píng)論

洪雅县| 汉沽区| 惠来县| 陆良县| 华池县| 勃利县| 始兴县| 新泰市| 汉寿县| 繁峙县| 岗巴县| 阿坝| 衡山县| 梁山县| 儋州市| 天峻县| 芦山县| 香港 | 荔波县| 钦州市| 政和县| 西和县| 车险| 嘉善县| 镇坪县| 鄂托克旗| 忻城县| 偃师市| 泽库县| 林周县| 徐闻县| 巴林右旗| 林芝县| 建宁县| 崇信县| 庆阳市| 象山县| 伊宁市| 郑州市| 克拉玛依市| 克拉玛依市|