在使用springboot的retry模块时,你是否出现过@recover注解失效的问题呢?下面我会对该问题进行复现,并且简要的说下解决方法。
首先我们引入maven
<dependency> <groupid>org.springframework.retry</groupid> <artifactid>spring-retry</artifactid> </dependency> <dependency> <groupid>org.aspectj</groupid> <artifactid>aspectjweaver</artifactid> <version>1.9.6</version> </dependency> <dependency> <groupid>cn.hutool</groupid> <artifactid>hutool-all</artifactid> <version>5.5.2</version> </dependency> <dependency> <groupid>org.projectlombok</groupid> <artifactid>lombok</artifactid> <optional>tr关于坚持的作文ue</optional> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-test</artifactid> <scope>test</scope> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency>
主类配置enableretry注解
package ai.guiji.csdn; import org.springframework.boot.springapplication;import org.springframework.boot.autoconfigure.springbootapplication;import org.springframework.retry.annotation.enableretry; @enableretry@springbootapplicationpublic class csdnapplication { public static void main(string[] args) { springapplication.run(csdnapplication.class, args); }}
准备测试的retry组件类代码
package ai.guiji.csdn.component; import lombok.extern.slf4j.slf4j;import org.springframework.retry.annotation.backoff;import org.springframework.retry.annotation.recover;import org.springframework.retry.annotation.retryable;import org.springframework.stereotype.component; import java.util.function.supplier; /** @author 剑客阿良_aliang @date 2021/4/22 16:07 @description: 重试工具 */@slf4j@componentpublic class retryutil { @retryable( value = exception.class, maxattempts = 3, backoff = @backoff(delay = 5000, multiplier = 1.5)) public string retry(supplier<string> supplier) throws exception { string result = null; try { result = supplier.get(); } catch (exception exception) { log.error("异常报错:{}", exception.getmessage()); throw exception; } return result; } @recover public void recover(exception e) { log.error("调用超过3次异常"); }}
代码说明
1、我们可以看到retry方法会重试supplier的get结果,捕获异常并抛出异常。这里抛出后会被retry捕获并且重试。
2、maxattempts参数为重试的最大次数。
3、backoff中的delay为两次重试之间的延迟,multiplier为重试阻尼,可以这么理解,每次重试间隔时间为上一次重试间隔时间的倍数。
4、如果3次重试均抛出异常,则进入recover方法。
编写测试代码
package ai.guiji.csdn.component; import cn.hutool.core.convert.convert;import cn.hutool.http.httputil;import org.junit.jupiter.api.test;import org.springframework.beans.factory.annotation.autowired;import org.springframework.boot.test.context.springboottest; /** @author 剑客阿良_alaing @date 2021/11/30 13:08 @description: */@springboottestclass retryutiltest { @autowired private retryutil retryutil; @test void retry() { try { system.out.println(convert.tostr(retryutil.retry(() -> httputil.post("xxxx", "")), "haha")); } catch (exception exception) { exception.printstacktrace(); } }}
执行测试结果
2021-11-30 13:37:44.012 error 13600 --- [ main] ai.guiji.csdn.component.retryutil : 异常报错:unknownhostexception: xxxx2021-11-30 13:37:49.019 error 13600 --- [ main] ai.guiji.csdn.component.retryutil : 异常报错:unknownhostexception: xxxx2021-11-30 13:37:58.787 error 13600 --- [ main] ai.guiji.csdn.component.retryutil : 异常报错:unknownhostexception: xxxxorg.springframework.retry.exhaustedretryexception: cannot locate recovery method; nested exception is cn.hutool.core.io.ioruntimeexception: unknownhostexception: xxxxat org.springframework.retry.annotation.recoverannotationrecoveryhandler.recover(recoverannotationrecoveryhandler.java:70)at org.springframework.retry.interceptor.retryoperationsinterceptor$itemrecoverercallback.recover(retryoperationsinterceptor.java:142)at org.springframework.retry.support.retrytemplate.handleretryexhausted(retrytemplate.java:539)at org.springframework.retry.support.retrytemplate.doexecute(retrytemplate.java:387)at org.springframework.retry.support.retrytemplate.execute(retrytemplate.java:225)at org.springframework.retry.interceptor.retryoperationsinterceptor.invoke(retryoperationsinterceptor.java:116)at org.springframework.retry.annotation.annotationawareretryoperationsinterceptor.invoke(annotationawareretryoperationsinterceptor.java:163)at org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:186)at org.springframework.aop.framework.cglibaopproxy$cglibmethodinvocation.proceed(cglibaopproxy.java:750)at org.springframework.aop.framework.cglibaopproxy$dynamicadvidinterceptor.intercept(cglibaopproxy.java:692)at ai.guiji.csdn.component.retryutil$$enhancerbyspringcglib$$d209cbc6.retry(<generated>)at ai.guiji.csdn.component.retryutiltest.retry(retryutiltest.java:17)at sun.reflect.nativemethodaccessorimpl.invoke0(native method)at sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)at sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)at java.lang.reflect.method.invoke(method.java:498)at org.junit.platform.commons.util.reflectionutils.invokemethod(reflectionutils.java:688)at org.junit.jupiter.engine.execution.methodinvocation.proceed(methodinvocation.java:60)at org.junit.jupiter.engine.execution.invocationinterceptorchain$validatinginvocation.proceed(invocationinterceptorchain.java:131)at org.junit.jupiter.engine.extension.timeoutextension.intercept(timeoutextension.java:149)at org.junit.jupiter.engine.extension.timeoutextension.intercepttestablemethod(timeoutextension.java:140)at org.junit.jupiter.engine.extension.timeoutextension.intercepttestmethod(timeoutextension.java:84)at org.junit.jupiter.engine.execution.executableinvoker$reflectiveinterceptorcall.lambda$ofvoidmethod$0(executableinvoker.java:115)at org.junit.jupiter.engine.execution.executableinvoker.lambda$invoke$0(executableinvoker.java:105)at org.junit.jupiter.engine.execution.invocationinterceptorchain$interceptedinvocation.proceed(invocationinterceptorchain.java:106)at org.junit.jupiter.engine.execution.invocationinterceptorchain.proceed(invocationinterceptorchain.java:64)at org.junit.jupiter.engine.execution.invocationinterceptorchain.chainandinvoke(invocationinterceptorchain.java:45)at org.junit.jupiter.engine.execution.invocationinterceptorchain.invoke(invocationinterceptorchain.java:37)at org.junit.jupiter.engine.execution.executableinvoker.invoke(executableinvoker.java:104)at org.junit.jupiter.engine.execution.executableinvoker.invoke(executableinvoker.java:98)at org.junit.jupiter.engine.descriptor.testmethodtestdescriptor.lambda$invoketestmethod$6(testmethodtestdescriptor.java:210)at org.junit.platform.engine.support.hierarchical.throwablecollector.execute(throwablecollector.java:73)at org.junit.jupiter.engine.descriptor.testmethodtestdescriptor.invoketestmethod(testmethodtestdescriptor.java:206)at org.junit.jupiter.engine.descriptor.testmethodtestdescriptor.execute(testmethodtestdescriptor.java:131)at org.junit.jupiter.engine.descriptor.testmethodtestdescriptor.execute(testmethodtestdescriptor.java:65)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$5(nodetesttask.java:139)at o员工餐厅管理制度rg.junit.platform.engine.support.hierarchical.throwablecollector.execute(throwablecollector.java:73)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$7(nodetesttask.java:129)at org.junit.platform.engine.support.hierarchical.node.around(node.java:137)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$8(nodetesttask.java:127)at org.junit.platform.engine.support.hierarchical.throwablecollector.execute(throwablecollector.java:73)at org.junit.platform.engine.support.hierarchical.nodetesttask.executerecursively(nodetesttask.java:126)at org.junit.platform.engine.support.hierarchical.nodetesttask.execute(nodetesttask.java:84)at java.util.arraylist.foreach(arraylist.java:1257)at org.junit.platform.engine.support.hierarchical.samethreadhierarchicaltestexecutorrvice.invokeall(samethreadhierarchicaltestexecutorrvice.java:38)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$5(nodetesttask.java:143)at org.junit.platform.engine.support.hierarchical.throwablecollector.execute(throwablecollector.java:73)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$7(nodetesttask.java:129)at org.junit.platform.engine.support.hierarchical.node.around(node.java:137)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$8(nodetesttask.java:127)at org.junit.platform.engine.support.hierarchical.throwablecollector.execute(throwablecollector.java:73)at org.junit.platform.engine.support.hierarchical.nodetesttask.executerecursively(nodetesttask.java:126)at org.junit.platform.engine.support.hierarchical.nodetesttask.execute(nodetesttask.java:84)at java.util.arraylist.foreach(arraylist.java:1257)at org.junit.platform.engine.support.hierarchical.samethreadhierarchicaltestexecutorrvice.李嘉诚全传invokeall(samethreadhierarchicaltestexecutorrvice.java:38)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$5(nodetesttask.java:143)at org.junit.platform.engine.support.hierarchical.throwablecollector.execute(throwablecollector.java:73)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$7(nodetesttask.java:129)at org.junit.platform.engine.support.hierarchical.node.around(node.java:137)at org.junit.platform.engine.support.hierarchical.nodetesttask.lambda$executerecursively$8(nodetesttask.java:127)at org.junit.platform.engine.support.hierarchical.throwablecollector.execute(throwablecollector.java:73)at org.junit.platform.engine.support.hierarchical.nodetesttask.executerecursively(nodetesttask.java:126)at org.junit.platform.engine.support.hierarchical.nodetesttask.execute(nodetesttask.java:84)at org.junit.platform.engine.support.hierarchical.samethreadhierarchicaltestexecutorrvice.submit(samethreadhierarchicaltestexecutorrvice.java:32)at org.junit.platform.engine.support.hierarchical.hierarchicaltestexecutor.execute(hierarchicaltestexecutor.java:57)at org.junit.platform.engine.support.hierarchical.hierarchicaltestengine.execute(hierarchicaltestengine.java:51)at org.junit.platform.launcher.core.engineexecutionorchestrator.execute(engineexecutionorchestrator.java:108)at org.junit.platform.launcher.core.engineexecutionorchestrator.execute(engineexecutionorchestrator.java:88)at org.junit.platform.launcher.core.engineexecutionorchestrator.lambda$execute$0(engineexecutionorchestrator.java:54)at org.junit.platform.launcher.core.engineexecutionorchestrator.withinterceptedstreams(engineexecutionorchestrator.java:67)at org.junit.platform.launcher.core.engineexecutionorchestrator.execute(engineexecutionorchestrator.java:52)at org.junit.platform.launcher.core.defaultlauncher.execute(defaultlauncher.java:96)at org.junit.platform.launcher.core.defaultlauncher.execute(defaultlauncher.java:75)at com.intellij.junit5.junit5ideatestrunner.startrunnerwithargs(junit5ideatestrunner.java:69)at com.intellij.rt.junit.ideatestrunner$repeater.startrunnerwithargs(ideatestrunner.java:33)at com.intellij.rt.junit.junitstarter.preparestreamsandstart(junitstarter.java:230)at com.intellij.rt.junit.junitstarter.main(junitstarter.java:58)caud by: cn.hutool.core.io.ioruntimeexception: unknownhostexception: xxxxat cn.hutool.http.httprequest.nd(httprequest.java:1153)at cn.hutool.http.httprequest.execute(httprequest.java:969)at cn.hutool.http.httprequest.execute(httprequest.java:940)at cn.hutool.http.httputil.post(httputil.java:216)at cn.hutool.http.httputil.post广西农业大学(httputil.java:197)at ai.guiji.csdn.component.retryutiltest.lambda$retry$0(retryutiltest.java:17)at ai.guiji.csdn.component.retryutil.retry(retryutil.java:22)at ai.guiji.csdn.component.retryutil$$fastclassbyspringcglib$$a565f63f.invoke(<generated>)at org.springframework.cglib.proxy.methodproxy.invoke(methodproxy.java:218)at org.springframework.aop.framework.cglibaopproxy$cglibmethodinvocation.invokejoinpoint(cglibaopproxy.java:779)at org.springframework.aop.framework.reflectivemethodinvocation.托福分数proceed(reflectivemethodinvocation.java:163)at org.springframework.aop.framework.cglibaopproxy$cglibmethodinvocation.proceed(cglibaopproxy.java:750)at org.springframework.retry.interceptor.retryoperationsinterceptor$1.dowithretry(retryoperationsinterceptor.java:93)at org.springframework.retry.support.retrytemplate.doexecute(retrytemplate.java:329)... 73 morecaud by: java.net.unknownhostexception: xxxxat java.net.abstractplainsocketimpl.connect(abstractplainsocketimpl.java:184)at java.net.plainsocketimpl.connect(plainsocketimpl.java:172)at java.net.sockssocketimpl.connect(sockssocketimpl.java:392)at java.net.socket.connect(socket.java:589)at java.net.socket.connect(socket.java:538)at sun.net.networkclient.doconnect(networkclient.java:180)at sun.net.www.http.httpclient.openrver(httpclient.java:463)at sun.net.www.http.httpclient.openrver(httpclient.java:558)at sun.net.www.http.httpclient.<init>(httpclient.java:242)at sun.net.www.http.httpclient.new(httpclient.java:339)at sun.net.www.http.httpclient.new(httpclient.java:357)at sun.net.www.protocol.http.httpurlconnection.getnewhttpclient(httpurlconnection.java:1220)at sun.net.www.protocol.http.httpurlconnection.plainconnect0(httpurlconnection.java:1156)at sun.net.www.protocol.http.httpurlconnection.plainconnect(httpurlconnection.java:1050)at sun.net.www.protocol.http.httpurlconnection.connect(httpurlconnection.java:984)at sun.net.www.protocol.http.httpurlconnection.getoutputstream0(httpurlconnection.java:1334)at sun.net.www.protocol.http.httpurlconnection.getoutputstream(httpurlconnection.java:1309)at cn.hutool.http.httpconnection.getoutputstream(httpconnection.java:451)at cn.hutool.http.httprequest.ndformurlencoded(httprequest.java:1176)at cn.hutool.http.httprequest.nd(httprequest.java:1145)... 86 moreprocess finished with exit code 0
并没有进入recover方法,注解未触发。
这里有个很容易忽视的点,就是retry方法是有返回值的,所以recover方法也必须是相同类型带返回值的方法。所以要把recover方法改一下。
package ai.guiji.csdn.component;import lombok.extern.slf4j.slf4j;import org.springframework.retry.annotation.backoff;import org.springframework.retry.annotation.recover;import org.springframework.retry.annotation.retryable;import org.springframework.stereotype.component;import java.util.function.supplier;/** @author 剑客阿良_aliang @date 2021/4/22 16:07 @description: 重试工具 */@slf4j@componentpublic class retryutil {@retryable(value = exception.class,maxattempts = 3,backoff = @backoff(delay = 5000, multiplier = 1.5))public string retry(supplier<string> supplier) throws exception {string result = null;try {result = supplier.get();} catch (exception exception) {log.error("异常报错:{}", exception.getmessage());throw exception;}return result;}@recoverpublic string recover(exception e) {log.error("调用超过3次异常");return "调用超过3次异常";}}
重新执行测试看下结果
以上就是springboot retry组件@recover失效问题解决方法的详细内容,更多关于springboot retry 解决@recover失效的资料请关注www.887551.com其它相关文章!
本文发布于:2023-04-03 23:17:09,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/9db6601f08dc01e72289ecb7f3f29ac0.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:Springboot Retry组件@Recover失效问题解决方法.doc
本文 PDF 下载地址:Springboot Retry组件@Recover失效问题解决方法.pdf
留言与评论(共有 0 条评论) |