首页 > 其他分享 >Feign失败重试与全局异常捕获

Feign失败重试与全局异常捕获

时间:2024-10-30 18:30:42浏览次数:1  
标签:status Feign 调用 return 捕获 重试 new response

feign注册

spring加载的时候通过@EnableFeignClients的FeignClientsRegistrar注册扫描所以得FeignClient以及Configuration,最终注册为ReflectiveFeign,最终通过代理类FeignInvocationHandler实现方法的调用,在
FeignInvocationHandler中通过SynchronousMethodHandler方法执行实际逻辑

当调用Feignclient里面的方法的时候最终会知道SynchronousMethodHandler的invoke方法

这里主要总结下feign的失败重试逻辑与异常捕获情况

feign异常

在SynchronousMethodHandler方法中会首先调用executeAndDecode方法,可以看到调用client.execute请求方法之后如果调用失败了则会执行errorExecuting直接返回RetryableException,

还有一个重要的方法是asyncResponseHandler.handleResponse,到这一步表示HTTP请求成功了,这里面将会根据响应码以及FeignClient中的方法返回类型反序列化来处理响应结果

首先判断是否为内定的Response类型,如果不是会根据项目配置的Decoder,可以根据自己需要配置fastjson或者jackjson以及其他的序列号工具

@Bean
    public Decoder feignDecoder() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.ALL);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(converter);
        return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
    }

如果是其他响应码会直接调用ErrorDecoder接口的decode()方法,默认的errorDecoder为ErrorDecoder.Default,默认返回FeignExcpetion,如果响应头当中含有Retry-After,则会返回RetryableException异常信息,进行后续逻辑来判断是否需要重试,但是这个默认的比较鸡肋,需要响应端提前在响应头加这个字段,调用第三方的接口时无法完成。

所以可以自己定义ErrorDecoder实现定制化的功能,比如只有当响应码为500的时候返回RetryableException后续进行重试

@Bean
        public ErrorDecoder errorDecoder() {
            return (methodKey, response) -> {
                FeignException exception = errorStatus(methodKey, response);
                if (response.status() >= 500 && response.status() <= 599) {
                    exception = new RetryableException(
                            response.status(),
                            exception.getMessage(),
                            response.request().httpMethod(),
                            exception,
                            null,
                            response.request());
                }
                return exception;
            };
        }

也可以自己根据响应码指定异常信息:

public class CustomErrorDecoder implements ErrorDecoder {
    @Override
    public Exception decode(String methodKey, Response response) {
        int status = response.status();
        switch (status) {
            case 400:
                return new CustomFeignException(status, "Bad Request");
            case 401:
                return new CustomFeignException(status, "Unauthorized");
            case 403:
                return new CustomFeignException(status, "Forbidden");
            case 404:
                return new CustomFeignException(status, "Not Found");
            case 500:
                return new CustomFeignException(status, "Internal Server Error");
            default:
                return new Exception(response.reason());
        }
    }
}

feign重试

如果前面步骤返回了RetryableException,则会调用Rtryer的continueOrPropagate方法,

默认为不重试,Reteyer里面内部类定义了一个Default重试方法,通过最大次数以及重试间隔来让线程休眠一段时间达到重试,在这期间调用FeignClient的线程一直处于阻塞中,所以重试不能间隔太长时间,这期间如果服务重启重试的线程则会直接断掉,所以如果不是页面操作调用接口的可以直接异步线程调用FeignClient的方法,或者自定义重试逻辑,存入延迟队列或者借助mq来处理调用失败的接口,

@Bean
    public Retryer retryer() {
        return new CustomRetryer(3, 1000); // 最多重试3次,每次间隔1秒
    }

ErrorDecode只有在请求成功的时候才会调用,如果连接超时或者网络错误,直接会抛出RetryableException,不会调用decode,所以不适合做全局异常处理

标签:status,Feign,调用,return,捕获,重试,new,response
From: https://www.cnblogs.com/LiuFqiang/p/18516296

相关文章

  • 微服务组件Feign远程调用介绍
    微服务组件Feign远程调用介绍一.什么是Feign以及Feign的使用介绍1.什么是Feign,Feign在微服务中扮演怎么样的角色?Feign是一个声明式的Web服务客户端,它使得编写HTTP客户端变得更简单。在微服务架构中,Feign通过注解的方式,将接口方法映射为HTTP请求,极大简化了微服务之......
  • stamina 生产级的python 重试包
    stamina是基于tenacity的包装包含的特性仅对某些异常(甚至是其中的子集)进行重试,方法是先使用谓词进行自检重试之间带有抖动的指数退避限制重试次数和总时间自动异步支持-包括Trio保留所装饰的可调用函数的类型提示开箱即用,可灵活使用Prometheus、structlog和标准库的支持l......
  • 《淘宝评论大探险:如何用API捕获消费者的心声?》
    在淘宝这个浩瀚的星系中,每一件商品都是一个星球,而评论就是星球上居民的声音。作为星际探险家,我们的任务是使用最尖端的科技——API,去捕获那些遥远星球上居民的心声。今天,我们要讲述的是如何装备你的代码宇宙飞船,飞向淘宝星系,捕获商品评论的数据。准备你的宇宙飞船:技术工具箱在......
  • openfeign使用中不能加@RequestMapping和@Async失效的情况总结
    1.openfeign使用中不能加@RequestMapping当在openfeign实现远程调用的时候,添加上了@RequestMapping注解,导致服务无法启动。控制台报错消息如下主要会产生三种问题:·与消费方服务原有接口产生冲突·多个协议包中的RPC接口冲突·使网关路由失效如图:原因:扫描到的FeignCli......
  • IDEA久违了!FeignX插件支持方法级别的导航跳转
    需求调研:发现身边的同事追踪业务代码的时候,如果遇见feign接口,大家都是通过全局搜url进一步找到远程服务的实现。一旦项目大起来,路径变得复杂甚至重名之后,这将会是灾难。市面上并没有很好的IDEA插件支持feign接口的解析以及相对应的远程服务之间的跳转,因此本人([lyflexi](https:......
  • Java的买家秀探秘:API数据的优雅捕获
    在编程世界的某个角落,Java特工正坐在他的高科技办公室里,沉浸在代码的海洋中。今天,他接到了一个有趣的任务:获取买家秀的API数据。这不仅是一次技术的挑战,更是一次深入了解买家心声的机会。Java特工,这位编程界的绅士,打开了他的IDE,准备开始这场优雅的探秘之旅。Java特工知道,要获......
  • python捕获鼠标键盘
    https://item.taobao.com/item.htm?from=cart&id=771194972569&pisk=f8nsFbjz51fs1GLwPtpUPW36bmrjcjtyctwxExINHlETGoMjerI2SlzbcXFEb5kaXSZjhYUxgSkNI2creGowSoSbjoqvaQ-y4ODgmoFaQ0_Nske7enSAX-KXde_DaQ-ycFBLcCOr_GiSnMe7eoeTk5Cpd-yVDshADkpQH-5OkGhvdvF3h1QAXrI......
  • iOS Swift 的捕获列表 [weak self] 和 [unowned self]
    捕获列表(capturelist)是Swift中闭包的重要概念之一,用来控制闭包如何捕获和存储其上下文中的外部变量。捕获行为在闭包中使用外部变量时,Swift会自动捕获这些变量的引用。如果这些变量是引用类型(如类实例),闭包会持有它们的强引用,可能导致强引用循环,即内存泄漏。捕获列表允许你......
  • 微服务之nacos&openfeign
    nacos使用方法:在docker容器中创建nacosdockerrun-d\--namenacos\--env-file./nacos/custom.env\-p8848:8848\-p9848:9848\-p9849:9849\--restart=always\nacos/nacos-server:v2.1.0-slim网址为ip:8848/nacos,账号密码都是nacos 服务注册:在pop.xml中引......
  • PBOOTCMS网站访问页面提示:您访问的页面不存在,请核对后重试!如何改成自动404跳转页面
    当用户访问PbootCMS网站时,如果请求的页面不存在,系统会显示一个错误页面,提示“您访问的页面不存在,请核对后重试!”。为了提升用户体验,可以将这个错误页面设置为1秒后自动跳转到其他页面,例如首页或指定的404页面。步骤打开错误页面模板文件:进入PbootCMS根目录,找到 core/......