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

news/2025/1/18 10:55:13/文章来源:https://www.cnblogs.com/LiuFqiang/p/18516296

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以及其他的序列号工具

@Beanpublic 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后续进行重试

@Beanpublic 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 {@Overridepublic 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来处理调用失败的接口,

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/824274.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

地下工程和深基坑监测预警系统建设方案

随着城市化进程的加快,地下工程和深基坑工程在城市建设中扮演着越来越重要的角色。这些工程的安全性直接关系到人民生命财产的安全和城市的正常运行。因此,建立一个科学、有效的地下工程和深基坑监测预警系统至关重要。 一、系统建设的必要性地下工程和深基坑工程在施工过程中…

25. 深浅拷贝

一、什么是浅拷贝只对对象的最顶层进行的拷贝称为 浅拷贝。我们可以用 copy 模块中的 copy() 方法实现浅拷贝。import copya = [11, 22, 33] b = [44, 55, 66] c = [a, b] d = copy.copy(c)print(f"c: {c}") print(f"d: {d}") print(f"c == d: {c == …

为什么我越来越喜欢用DDD — DDD架构篇(1)

Hello DDDDDD 是一种软件设计方法,DDD 是指导我们做软件工程设计的一种手段。它提供了用切割工程模型的各类技巧,如;领域、界限上下文、实体、值对象、聚合、工厂、仓储等。通过 DDD 的指导思想,我们可以在前期投入更多的时间,更加合理的规划出可持续迭代的工程设计。 在D…

SpringBoot3.0整合Mybatis-plus实现多数据源(重构类方式)

背景 前段时间在做一个数据中台的项目,系统用到了不同数据库中的数据。自己又不想手写JDBC连接,既然我有这个需求,那功能应该有人实现了,于是开始了网上搜了,搜索后发现基本都是讲读写分离、主备切换的,后面也查略了Mybatis-plus的官网,里面有这个功能,但好像是我组件的…

58. 区间和

题目 本人一开始是这样写的: #include <iostream>using namespace std;const int N = 100010; int n; int s[N];int main() {cin >> n;for (int i = 1; i <= n; i ++ ){int x;cin >> x;s[i] = s[i - 1] + x;}int l = 0, r = 0;while (cin >> l &am…

cin和scanf的返回值知多少

cin的返回值 在 C++ 中,cin 是用于从标准输入(通常是键盘)读取数据的对象。 cin 的返回值实际上是一个流对象(std::istream 类型),可以通过流的状态来检查输入操作是否成功。 以下是一些关于 cin 返回值的关键点:输入成功与失败: 当你使用 cin 进行输入时,可以通过 ci…

多语言 AI 翻译 API 数据接口

多语言 AI 翻译 API 数据接口 ai / 翻译 基于 AI 多语言模型 支持多语言 / 基于模型。1. 产品功能基于自有专业模型进行 AI 多语言翻译 高效的文本翻译性能 全接口支持 HTTPS(TLS v1.0 / v1.1 / v1.2 / v1.3); 全面兼容 Apple ATS; 全国多节点 CDN 部署; 接口极速响应,多…

个人可识别信息(PII) AI 去除 API 数据接口

个人可识别信息(PII) AI 去除 API 数据接口 ai / 隐私保护 基于 AI 模型自动去除个人识别信息(PII) 个人信息保护 / AI 模型 。1. 产品功能基于自有专业模型进行 PII 自动去除 高效处理敏感信息 全接口支持 HTTPS(TLS v1.0 / v1.1 / v1.2 / v1.3); 全面兼容 Apple ATS; 全…

MBR20100CT-ASEMI半塑封肖特基二极管MBR20100CT

MBR20100CT-ASEMI半塑封肖特基二极管MBR20100CT编辑:ll MBR20100CT-ASEMI半塑封肖特基二极管MBR20100CT 型号:MBR20100CT 品牌:ASEMI 封装:TO-220 安装方式:插件 批号:最新 最大平均正向电流(IF):20A 最大循环峰值反向电压(VRRM):100V 最大正向电压(VF):0.70V~0…

第三十讲:误删数据后除了跑路,还能怎么办?

第三十讲:误删数据后除了跑路,还能怎么办? 简概还是平淡的开头 ​ 今天我要和你讨论的是一个沉重的话题:误删数据。 ​ 在前面几篇文章中,我们介绍了 MySQL 的高可用架构。 ​ 当然,传统的高可用架构是不能预防误删数据的,因为主库的一个 drop table 命令,会通过 binlo…

TYPE-C PD浅谈(一)

聊聊USB Power Delivery两三事,接下来会依下列几个主题来探讨What is Power Delivery E-Marker Attached Source CAP Sink CAP Power Role Swap Data Role Swap VCONN Swap Alternate Mode Charger Design Note What is Power DeliveryUSB界面历经20年的演变,在界面上一直没有…