这可能是Feign调用可重试的优秀方案了_天天快播报


【资料图】

Feign​重试其实是一个很常见的场景,我们本文通过了自定义了一个@FeignRetry​注解来实现可重试的机制,针对不同的Feign接口还可以使用不同的重试策略,是不是很方便,快在你的项目中用起来吧。

前言

在我们公司里,不同的服务之间通过Feign进行远程调用,但是,我们在尝试使调用可重试时遇到了一个小问题,Feign框架本身可以配置的自己的重试机制,但是它是一刀切的方式,所有的调用都是同样的机制,没有办法像我们希望的那样在每个方法的基础上配置。不过我在项目中探索除了一种新的写法,通过spring-retry框架集合Feign去实现重试机制,可以为每个调用实现不同的重试机制,那究竟是如何做到的呢,继续往下看呀。

自定义注解@FeignRetry

为了解决上面提到的问题,让Feign调用的每个接口单独配置不同的重试机制。我们使用了面向切面编程并编写了一个自定义注解:@FeignRetry。此注释的工作方式类似于@Retryable的包装器,并与其共享相同的规范以避免混淆。

@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface FeignRetry {    Backoff backoff() default @Backoff();    int maxAttempt() default 3;    Class[] include() default {};}@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Backoff {    long delay() default 1000L;;    long maxDelay() default 0L;    double multiplier() default 0.0D;;}

FeignRetryAspect切面处理@FeignRetry注解。

Slf4j@Aspect@Componentpublic class FeignRetryAspect {    @Around("@annotation(FeignRetry)")    public Object retry(ProceedingJoinPoint joinPoint) throws Throwable {        Method method = getCurrentMethod(joinPoint);        FeignRetry feignRetry = method.getAnnotation(FeignRetry.class);        RetryTemplate retryTemplate = new RetryTemplate();        retryTemplate.setBackOffPolicy(prepareBackOffPolicy(feignRetry));        retryTemplate.setRetryPolicy(prepareSimpleRetryPolicy(feignRetry));        // 重试        return retryTemplate.execute(arg0 -> {            int retryCount = arg0.getRetryCount();            log.info("Sending request method: {}, max attempt: {}, delay: {}, retryCount: {}",                    method.getName(),                    feignRetry.maxAttempt(),                    feignRetry.backoff().delay(),                    retryCount            );            return joinPoint.proceed(joinPoint.getArgs());        });    }    private BackOffPolicy prepareBackOffPolicy(FeignRetry feignRetry) {        if (feignRetry.backoff().multiplier() != 0) {            ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();            backOffPolicy.setInitialInterval(feignRetry.backoff().delay());            backOffPolicy.setMaxInterval(feignRetry.backoff().maxDelay());            backOffPolicy.setMultiplier(feignRetry.backoff().multiplier());            return backOffPolicy;        } else {            FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();            fixedBackOffPolicy.setBackOffPeriod(feignRetry.backoff().delay());            return fixedBackOffPolicy;        }    }    private SimpleRetryPolicy prepareSimpleRetryPolicy(FeignRetry feignRetry) {        Map, Boolean> policyMap = new HashMap<>();        policyMap.put(RetryableException.class, true);  // Connection refused or time out        policyMap.put(ClientException.class, true);     // Load balance does not available (cause of RunTimeException)        if (feignRetry.include().length != 0) {            for (Class t : feignRetry.include()) {                policyMap.put(t, true);            }        }        return new SimpleRetryPolicy(feignRetry.maxAttempt(), policyMap, true);    }    private Method getCurrentMethod(JoinPoint joinPoint) {        MethodSignature signature = (MethodSignature) joinPoint.getSignature();        return signature.getMethod();    }}

捕获FeignRetry注解的方法,将配置传递给Spring RetryTemplate,根据配置调用服务。

@FeignRetry 的使用

用法很简单,只需将注释放在我们希望重试机制处于活动状态的Feign Client方法上即可。自定义切面的用法类似于Spring自带的@Retryable注解。

@GetMapping@FeignRetry(maxAttempt = 3, backoff = @Backoff(delay = 500L))ResponseEntity retrieve1();@GetMapping@FeignRetry(maxAttempt = 6, backoff = @Backoff(delay = 500L, maxDelay = 20000L, multiplier = 4))ResponseEntity retrieve2();

另外还需要在应用程序类中使用@EnableRetry注释来启动重试,比如可以加载SpringBoot的启动类中。

总结

Feign重试其实是一个很常见的场景,我们本文通过了自定义了一个@FeignRetry注解来实现可重试的机制,针对不同的Feign接口还可以使用不同的重试策略,是不是很方便,快在你的项目中用起来吧。

关键词:

为您推荐

这可能是Feign调用可重试的优秀方案了_天天快播报

Feign​重试其实是一个很常见的场景,我们本文通过了自定义了一个@FeignRetry​注解来实现可重试的机制,针

来源:清一色财经2023-05-06

乘客吐槽绍兴北站成“水帘洞” 相关部门回应:瞬间流量超设计流量 正在整改

5月5日下午,有网友在某短视频平台发布视频,介绍自己在绍兴北站搭乘高铁时,发现出站口等多个地方的天花板

来源:上游新闻2023-05-06

#(科技)我国大洋钻探船北部码头启用

当日,自然资源部中国地质调查局大洋钻探船北部码头在山东青岛揭牌。该码头位于青岛市即墨区柴岛西侧,是我

来源:新华社2023-05-06

应届生遭事业单位“故意违约”,如此“筑巢引凤”让人看不懂

近日,南宁师范大学应届毕业生小优(化名)参与了广东省云浮市云浮中学的线下招聘会,面试顺利,与云浮中学

来源:正观新闻2023-05-06

世界即时看!戴两层面具起舞《歌剧魅影》,吴虎生:我的心被魅影占了

经过三个月打磨,舞剧形态已成,团队也越来越默契,他的内心涌动着喜悦,却又包裹着一层悲伤,“我的心和魅

来源:澎湃新闻2023-05-06

哈登赌城曝光,里弗斯调侃

北京时间5月6日,76人主场迎战凯尔特人,双方前两场战成1-1平。赛前,76人主帅里弗斯接受采访,透露了哈登

来源:罗说篮球2023-05-06

“五一”假期多项数据创新高 带动中国经济回暖_全球要闻

新华社北京5月6日电中国文化和旅游部3日公布数据,“五一”假期全国国内旅游出游合计2 74亿人次,按可比口

来源:新华网2023-05-06

2寸 美图秀秀-美图秀秀在线制作2寸照片|环球今亮点

1、首先,双击电脑上的美图秀秀图标,打开软件,点击美化图片,导入想要裁剪的图片。2、2、导入之后,点击

来源:互联网2023-05-06