日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

SpringBoot @Retryable注解方式

瀏覽:37日期:2023-04-23 10:20:37

背景

在調用第三方接口或者使用MQ時,會出現網絡抖動,連接超時等網絡異常,所以需要重試。為了使處理更加健壯并且不太容易出現故障,后續的嘗試操作,有時候會幫助失敗的操作最后執行成功。一般情況下,需要我們自行實現重試機制,一般是在業務代碼中加入一層循環,如果失敗后,再嘗試重試,但是這樣實現并不優雅。在SpringBoot中,已經實現了相關的能力,通過@Retryable注解可以實現我們想要的結果。

@Retryable

首先來看一下Spring官方文檔的解釋:

SpringBoot @Retryable注解方式

@Retryable注解可以注解于方法上,來實現方法的重試機制。

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>

使用實例

SpringBoot retry的機制比較簡單,只需要兩個注解即可實現。

啟動類

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

在啟動類上,需要加入@EnableRetry注解,來開啟重試機制。

Service類

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

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

來簡單解釋一下注解中幾個參數的含義:

名稱 含義 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的參數列表,參數較多,這里就選擇幾個主要的來說明一下:

interceptor:可以通過該參數,指定方法攔截器的bean名稱

value:拋出指定異常才會重試

include:和value一樣,默認為空,當exclude也為空時,默認所以異常

exclude:指定不處理的異常

maxAttempts:最大重試次數,默認3次

backoff:重試等待策略,默認使用@Backoff,@Backoff的value默認為1000L,我們設置為2000L;multiplier(指定延遲倍數)默認為0,表示固定暫停1秒后進行重試,如果把multiplier設置為1.5,則第一次重試為2秒,第二次為3秒,第三次為4.5秒。

我們把上面的例子執行一下,來看看效果:

2019-12-25 11:38:02.492 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統2019-12-25 11:38:02.493 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統2019-12-25 11:38:04.494 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統2019-12-25 11:38:04.495 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統2019-12-25 11:38:07.496 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統2019-12-25 11:38:07.496 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統2019-12-25 11:38:11.997 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 開始通知下游系統2019-12-25 11:38:11.997 INFO 25664 --- [ main] c.f.l.service.impl.DoRetryServiceImpl : 通知下游系統java.lang.RuntimeException: 通知下游系統異常.........

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

@Recover

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

@Recover

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

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

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

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

/** * 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不生效的問題

在測試過程中,發現@Recover無法生效,執行時拋出異常信息:

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)

追蹤一下異常的信息,進入到RecoverAnnotationRecoveryHandler中,找到報錯的方法public T recover(Object[] args, Throwable cause),看一下其實現:

SpringBoot @Retryable注解方式

發現報錯處,是因為method為空而導致的,明明我已經在需要執行的方法上注解了@Recover,為什么還會找不到方法呢?很奇怪,再來深入追蹤一下:

SpringBoot @Retryable注解方式

打斷點到這,發現methods列表是空的,那么methods列表是什么時候初始化的呢?繼續追蹤:

SpringBoot @Retryable注解方式

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

SpringBoot @Retryable注解方式

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

我有點懷疑Spring掃描的部分,可能有什么問題了,回頭去看看@EnableRetry是怎么說的:

SpringBoot @Retryable注解方式

終于找到問題的所在了,對于@EnableRetry中的proxyTargetClass參數,是控制是否對使用接口實現的bean開啟代理類,默認的情況下,是不開啟的,問題原因就是這個,我們來實驗一下,把這個參數改成true:

@EnableRetry(proxyTargetClass = true)

再次運行,果然沒有問題了。

由此得出結論,當使用接口實現的bean時,需要將EnableRetry的參數改為true,非接口的實現,可以使用默認配置,即false。

結語

本篇主要簡單介紹了Springboot中的Retryable的使用,主要的適用場景為在調用第三方接口或者使用MQ時。由于會出現網絡抖動,連接超時等網絡異常。

以上這篇SpringBoot @Retryable注解方式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
av免费不卡国产观看| 亚洲欧美日韩在线观看a三区| 精品亚洲a∨| 欧美精选视频一区二区| 亚洲日本免费电影| 色婷婷成人网| 秋霞国产精品| 国产精品欧美一区二区三区不卡| 日韩国产一区二| 麻豆视频在线看| 国产精品一国产精品k频道56| 国内自拍视频一区二区三区| 丝袜美腿亚洲一区二区图片| 国产精品777777在线播放| 午夜久久av | 国模精品一区| 不卡在线一区二区| 欧美在线91| 在线视频亚洲欧美中文| 欧美a在线观看| 亚洲精品伊人| 亚洲天堂久久| 久久国产主播| 欧美另类综合| 免费在线成人网| 成人午夜网址| 三级欧美韩日大片在线看| 色88888久久久久久影院| 亚洲人成在线网站| 久久成人高清| 国产精品中文字幕制服诱惑| 亚洲涩涩av| 国产精品日韩| 午夜国产精品视频| 日韩国产一区二区三区| 日韩电影免费网站| 久久人人精品| 欧美日韩在线观看视频小说| 亚洲精品麻豆| 亚洲专区视频| 三级一区在线视频先锋| 欧美成人高清| 国产农村妇女精品一区二区| 五月天久久777| 欧美日韩国产亚洲一区| 日韩一区亚洲二区| 精品国产欧美日韩| 亚洲成av在线| 久久精品 人人爱| 国产精品a级| 蜜臀国产一区| 99riav1国产精品视频| 亚洲精品影院在线观看| 宅男在线一区| 欧美午夜不卡| 男人的天堂久久精品| 亚久久调教视频| 在线综合亚洲| 亚洲日韩视频| 亚洲综合婷婷| 麻豆91精品91久久久的内涵| 羞羞答答国产精品www一本| 亚洲成人精品| 成人精品天堂一区二区三区| 精品视频一区二区三区四区五区 | 在线 亚洲欧美在线综合一区| 欧美激情aⅴ一区二区三区| 日韩黄色在线观看| 日韩1区2区日韩1区2区| 午夜精品影视国产一区在线麻豆| 在线视频精品| 蜜臀国产一区二区三区在线播放| 9久re热视频在线精品| 伊人久久婷婷| 中文不卡在线| 日韩视频一二区| 日本久久二区| 免费一区二区三区在线视频| 久久久久伊人| 另类专区亚洲| 日韩中文欧美| 亚洲高清不卡| 国产精品久久777777毛茸茸| 蜜芽一区二区三区| 久久麻豆精品| 在线看片福利| 久久国产66| 亚洲韩日在线| 精品三级久久久| 91精品高清| 日韩中文字幕高清在线观看| 日韩制服丝袜先锋影音| 91麻豆精品| 啪啪国产精品| 日韩国产成人精品| 麻豆久久一区| 丝袜美腿亚洲色图| 日韩大片在线播放| 日本天堂一区| 在线国产一区| 成人国产精品久久| 日本视频一区二区| 男女男精品视频网| 99久久99久久精品国产片果冰| 欧美一级二级三级视频| 亚洲成人不卡| 麻豆视频久久| 91视频精品| 亚洲区欧美区| 黑丝一区二区| 婷婷激情图片久久| 欧美黑人做爰爽爽爽| 成人久久一区| 国产高清不卡| 国产精品嫩草99av在线| 日韩精品国产精品| 免费一级欧美在线观看视频| 久久av网站| 99久久精品网站| 欧美精品资源| 国产aⅴ精品一区二区四区| 日韩高清不卡在线| 亚洲人成亚洲精品| 国产一区二区精品| 精品一区在线| 国产999精品在线观看| 九九99久久精品在免费线bt| 日韩va亚洲va欧美va久久| 少妇精品久久久一区二区三区| 婷婷亚洲五月| 红桃视频欧美| 午夜久久美女| 久久aⅴ国产紧身牛仔裤| 在线国产一区二区| 狠狠干成人综合网| 一区二区三区四区在线观看国产日韩| 视频一区在线播放| 久久亚洲影院| 国产亚洲一区二区三区不卡| 欧美激情综合| 精品淫伦v久久水蜜桃| 卡一卡二国产精品| 日韩免费在线| 首页国产欧美日韩丝袜| 日韩av一区二区在线影视| 91精品国产自产精品男人的天堂 | 国产调教一区二区三区| 美女久久久久久| 日韩久久精品| 蜜臀91精品一区二区三区| 日本不卡视频在线观看 | 久久国内精品| 日韩电影免费在线观看| 国产毛片一区| 国产三级精品三级在线观看国产| 麻豆国产精品| 五月综合激情| 久久国产精品美女| 欧美搞黄网站| 国产精品尤物| 老司机久久99久久精品播放免费| 日韩在线网址| 综合激情五月婷婷| 米奇777超碰欧美日韩亚洲| 麻豆国产欧美日韩综合精品二区| 中文无码久久精品| 久久九九99| 国产伦久视频在线观看| 国产精品久久久久av蜜臀| 日韩精品视频中文字幕| 欧美在线综合| 欧美日韩精品免费观看视完整| 国产亚洲一区二区三区啪| 亚洲人成在线影院| 综合国产精品| 久久亚洲一区| 国产亚洲精品v| 欧美日韩日本国产亚洲在线| 日韩天堂在线| 91精品国产福利在线观看麻豆| 精品成人免费一区二区在线播放| 国产精品福利在线观看播放| 久久精品国产一区二区| 日韩精品视频在线看| 91麻豆精品| 麻豆国产91在线播放| 久久一区亚洲| 美女福利一区二区三区| 日韩欧美精品综合| 亚洲国内精品| 亚洲欧美日韩精品一区二区| 日韩精品一级二级| 人人爽香蕉精品| 国产九九精品| 成人一二三区| 成人av动漫在线观看| 黄色免费成人| 国产亚洲精品美女久久 | 免费在线观看视频一区| 国产剧情在线观看一区|