电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

SpringBoot @Retryable注解方式

瀏覽:4日期: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
相關文章:
主站蜘蛛池模板: 首页-浙江橙树网络技术有限公司 石磨面粉机|石磨面粉机械|石磨面粉机组|石磨面粉成套设备-河南成立粮油机械有限公司 | 锂电池生产厂家-电动自行车航模无人机锂电池定制-世豹新能源 | 蔡司三坐标-影像测量机-3D扫描仪-蔡司显微镜-扫描电镜-工业CT-ZEISS授权代理商三本工业测量 | 3d打印服务,3d打印汽车,三维扫描,硅胶复模,手板,快速模具,深圳市精速三维打印科技有限公司 | 硫化罐-胶管硫化罐-山东鑫泰鑫智能装备有限公司 | Type-c防水母座|贴片母座|耳机接口|Type-c插座-深圳市步步精科技有限公司 | 美的商用净水器_美的直饮机_一级代理经销商_Midea租赁价格-厂家反渗透滤芯-直饮水批发品牌售后 | 大倾角皮带机-皮带输送机-螺旋输送机-矿用皮带输送机价格厂家-河南坤威机械 | 减速机电机一体机_带电机减速器一套_德国BOSERL电动机与减速箱生产厂家 | 深圳APP开发_手机软件APP定制外包_小程序开发公司-来科信 | 烟气在线监测系统_烟气在线监测仪_扬尘检测仪_空气质量监测站「山东风途物联网」 | 软文发布平台 - 云软媒网络软文直编发布营销推广平台 | 粉末包装机-给袋式包装机-全自动包装机-颗粒-液体-食品-酱腌菜包装机生产线【润立机械】 | 上海办公室装修,写字楼装修—启鸣装饰设计工程有限公司 | 航空障碍灯_高中低光强航空障碍灯_民航许可认证航空警示灯厂家-东莞市天翔航天科技有限公司 | 德国BOSCH电磁阀-德国HERION电磁阀-JOUCOMATIC电磁阀|乾拓百科 | 一级建造师培训_一建培训机构_中建云筑建造师培训网校 | 热熔胶网膜|pes热熔网膜价格|eva热熔胶膜|热熔胶膜|tpu热熔胶膜厂家-苏州惠洋胶粘制品有限公司 | 工业铝型材-铝合金电机壳-铝排-气动执行器-山东永恒能源集团有限公司 | 郑州大巴车出租|中巴车租赁|旅游大巴租车|包车|郑州旅游大巴车租赁有限公司 | 南京技嘉环保科技有限公司-杀菌除臭剂|污水|垃圾|厕所|橡胶厂|化工厂|铸造厂除臭剂 | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 上海质量认证办理中心| 双工位钻铣攻牙机-转换工作台钻攻中心-钻铣攻牙机一体机-浙江利硕自动化设备有限公司 | 热缩管切管机-超声波切带机-织带切带机-无纺布切布机-深圳市宸兴业科技有限公司 | 非标压力容器_碳钢储罐_不锈钢_搪玻璃反应釜厂家-山东首丰智能环保装备有限公司 | 潍坊大集网-潍坊信息港-潍坊信息网 | 中开泵,中开泵厂家,双吸中开泵-山东博二泵业有限公司 | 全自动端子机|刺破式端子压接机|全自动双头沾锡机|全自动插胶壳端子机-东莞市傅氏兄弟机械设备有限公司 | 仿真茅草_人造茅草瓦价格_仿真茅草厂家_仿真茅草供应-深圳市科佰工贸有限公司 | 北京工业设计公司-产品外观设计-产品设计公司-千策良品工业设计 北京翻译公司-专业合同翻译-医学标书翻译收费标准-慕迪灵 | 学叉车培训|叉车证报名|叉车查询|叉车证怎么考-工程机械培训网 | 示波器高压差分探头-国产电流探头厂家-南京桑润斯电子科技有限公司 | 石家庄网站建设|石家庄网站制作|石家庄小程序开发|石家庄微信开发|网站建设公司|网站制作公司|微信小程序开发|手机APP开发|软件开发 | 智慧农业|农业物联网|现代农业物联网-托普云农物联网官方网站 | 不干胶标签-不干胶贴纸-不干胶标签定制-不干胶标签印刷厂-弗雷曼纸业(苏州)有限公司 | 礼仪庆典公司,礼仪策划公司,庆典公司,演出公司,演艺公司,年会酒会,生日寿宴,动工仪式,开工仪式,奠基典礼,商务会议,竣工落成,乔迁揭牌,签约启动-东莞市开门红文化传媒有限公司 | 硅胶布|电磁炉垫片|特氟龙胶带-江苏浩天复合材料有限公司 | 【ph计】|在线ph计|工业ph计|ph计厂家|ph计价格|酸度计生产厂家_武汉吉尔德科技有限公司 | 直齿驱动-新型回转驱动和回转支承解决方案提供商-不二传动 | 亮点云建站-网站建设制作平台|