笔记本远程过程调用失败且未执行,电脑桌面显示远程过程调用失败

首页 > 实用技巧 > 作者:YD1662023-11-28 21:50:43

上面的代码可以看到是有效果了,虽然不是很好看,特别是在还有一些其他逻辑的情况,看上去会很臃肿,但是确实是可以正常使用的,那么有的小伙伴就要问了,有没有一种优雅的方式呢?总不能在很多地方都重复的这样写重试的代码吧。

注解重试

要知道我们普通人在日常开发的时候,如果遇到一个问题肯定是别人都遇到过的,什么时候当我们遇到的问题,没有人遇到过的时候,那说明我们是很前卫的。

因此小伙伴能想到的是不是有简单的方式来进行重试,有的人已经帮我们想好了,可以通过 @Retryable 注解来实现一样的效果,接下来阿粉就给大家演示一下如何使用这个注解。

首先我们需要在启动类上面加入 @EnableRetry​ 注解,表示要开启重试的功能,这个很好理解,就像我们要开启定时功能需要添加 @EnableScheduling​ 注解一样,Spring​ 的 @Enablexxx 注解也是很有意思的,后面我们再聊。

添加完注解以后,需要加入切面的依赖,如下

<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.2</version> </dependency>

如下不加入这个切面依赖,启动的时候会有如下异常

笔记本远程过程调用失败且未执行,电脑桌面显示远程过程调用失败(5)

添加的注解和依赖过后,我们需要改造 HelloService​ 里面的 sayHello()​ 方法,简化成如下,增加 @Retryable 注解,以及设置相应的参数值。

@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 1000, multiplier = 2)) public String sayHello(String name){ return name doSomething(); }

再次通过浏览器访问 http://127.0.0.1:8080/hello?name=ziyou 我们看到效果如下,跟我们自己写的重试一样。

笔记本远程过程调用失败且未执行,电脑桌面显示远程过程调用失败(6)

@Retryable 详解

// // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // package org.springframework.retry.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Retryable { String recover() default ""; String interceptor() default ""; Class<? extends Throwable>[] value() default {}; Class<? extends Throwable>[] include() default {}; Class<? extends Throwable>[] exclude() default {}; String label() default ""; boolean stateful() default false; int maxAttempts() default 3; String maxAttemptsExpression() default ""; Backoff backoff() default @Backoff; String exceptionExpression() default ""; String[] listeners() default {}; }

点到这个注解里面,我们可以看到这个注解的代码如下,其中有几个参数我们来解释一下

配合上面的一些属性的使用,我们就可以达到通过注解简单来实现方法调用异常后的自动重试,非常好用。我们可以在执行重试方法的时候设置自定义的重试拦截器,如下所示,自定义重试拦截器需要实现 MethodInterceptor​ 接口并实现 invoke 方法,不过要注意,如果使用了拦截器的话,那么方法上的参数就会被覆盖。

package com.example.demo.pid; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.retry.interceptor.RetryInterceptorBuilder; import org.springframework.retry.interceptor.RetryOperationsInterceptor; import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.stereotype.Component; @Component public class CustomRetryInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { RetryOperationsInterceptor build = RetryInterceptorBuilder.stateless() .maxAttempts(2).backOffOptions(3000, 2, 1000).build(); return build.invoke(invocation); } }

自定义回滚方法,我们还可以在重试几次依旧错误的情况,编写自定义的回滚方法。

@Retryable(value = Exception.class, recover = "recover", maxAttempts = 2, backoff = @Backoff(delay = 1000, multiplier = 2)) public String sayHello(String name){ return name doSomething(); } @Recover public String recover(Exception e, String name) { System.out.println("recover"); return "recover"; }

笔记本远程过程调用失败且未执行,电脑桌面显示远程过程调用失败(7)

要注意:

上面代码中的 @Backoff(delay = 1000, multiplier = 2) 表示第一次延迟 1000ms 重试,后面每次重试的延迟时间都翻倍。

总结

阿粉今天给大家介绍了一下 Spring​ 的 @Retryable 注解使用,并通过几个 demo 来带大家编写了自己重试拦截器以及回滚方法的时候,是不是感觉用起来会很爽,那还在等什么赶紧用起来吧,其中还有很多细节,只有自己真正的使用过才能体会到。

上一页12末页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.