spring boot 2.4.x 之前版本(对应spring-cloud-openfeign 3.0.0之前版本)feign请求异常逻辑

目录

feign

SynchronousMethodHandler

第一部分

第二部分

第三部分

spring-cloud-openfeign

LoadBalancerFeignClient

ribbon

AbstractLoadBalancerAwareClient


在之前写的文章配置基础上

https://blog.csdn.net/zlpzlpzyd/article/details/136060312

因为从 spring boot 2.4.x 版本开始,匹配的 spring cloud 版本中去除了负载均衡组件 ribbon,可以看本人写的如下链接

https://blog.csdn.net/zlpzlpzyd/article/details/135696320

如果一定要使用 ribbon 相关功能,需要单独指定版本引入,spring 官方为了 ribbon 被移除的问题,自己开发了 spring-cloud-starter-loadbalancer。

feign设置参数如下

feign:client:config:default:connectTimeout: 1000readTimeout: 1000

服务提供者逻辑

@RestController
@RequestMapping(value = "user")
public class UserController implements Serializable {@GetMapping(value = "{id}")public User getUser(@PathVariable(value = "id") String id) {// int no = 1/0;try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {throw new RuntimeException(e);}User user = new User();user.setId(id);user.setUserName("user_name_"+ id);user.setAge("20");return user;}}

可知,feign 调用此服务会出现超时问题。

异常堆栈调用如下

0 = {StackTraceElement@8542} "java.net.SocketInputStream.socketRead0(Native Method)"
1 = {StackTraceElement@8543} "java.net.SocketInputStream.socketRead(SocketInputStream.java:116)"
2 = {StackTraceElement@8544} "java.net.SocketInputStream.read(SocketInputStream.java:171)"
3 = {StackTraceElement@8545} "java.net.SocketInputStream.read(SocketInputStream.java:141)"
4 = {StackTraceElement@8546} "java.io.BufferedInputStream.fill(BufferedInputStream.java:246)"
5 = {StackTraceElement@8547} "java.io.BufferedInputStream.read1(BufferedInputStream.java:286)"
6 = {StackTraceElement@8548} "java.io.BufferedInputStream.read(BufferedInputStream.java:345)"
7 = {StackTraceElement@8549} "sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)"
8 = {StackTraceElement@8550} "sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)"
9 = {StackTraceElement@8551} "sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1593)"
10 = {StackTraceElement@8552} "sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)"
11 = {StackTraceElement@8553} "java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)"
12 = {StackTraceElement@8554} "feign.Client$Default.convertResponse(Client.java:113)"
13 = {StackTraceElement@8555} "feign.Client$Default.execute(Client.java:109)"
14 = {StackTraceElement@8556} "org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer.execute(FeignLoadBalancer.java:98)"
15 = {StackTraceElement@8557} "org.springframework.cloud.openfeign.ribbon.FeignLoadBalancer.execute(FeignLoadBalancer.java:56)"
16 = {StackTraceElement@8558} "com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:103)"
17 = {StackTraceElement@8559} "com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303)"
18 = {StackTraceElement@8560} "com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287)"
19 = {StackTraceElement@8561} "rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:231)"
20 = {StackTraceElement@8562} "rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:228)"
21 = {StackTraceElement@8563} "rx.Observable.unsafeSubscribe(Observable.java:10327)"
22 = {StackTraceElement@8564} "rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286)"
23 = {StackTraceElement@8565} "rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.onNext(OnSubscribeConcatMap.java:144)"
24 = {StackTraceElement@8566} "com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:185)"
25 = {StackTraceElement@8567} "com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)"
26 = {StackTraceElement@8568} "rx.Observable.unsafeSubscribe(Observable.java:10327)"
27 = {StackTraceElement@8569} "rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94)"
28 = {StackTraceElement@8570} "rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42)"
29 = {StackTraceElement@8571} "rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)"
30 = {StackTraceElement@8572} "rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)"
31 = {StackTraceElement@8573} "rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)"
32 = {StackTraceElement@8574} "rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)"
33 = {StackTraceElement@8575} "rx.Observable.subscribe(Observable.java:10423)"
34 = {StackTraceElement@8576} "rx.Observable.subscribe(Observable.java:10390)"
35 = {StackTraceElement@8577} "rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:443)"
36 = {StackTraceElement@8578} "rx.observables.BlockingObservable.single(BlockingObservable.java:340)"
37 = {StackTraceElement@8579} "com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:110)"
38 = {StackTraceElement@8580} "org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:84)"
39 = {StackTraceElement@8581} "feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:125)"
40 = {StackTraceElement@8582} "feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:94)"
41 = {StackTraceElement@8583} "feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)"
42 = {StackTraceElement@8584} "com.sun.proxy.$Proxy71.getUser(Unknown Source)"
43 = {StackTraceElement@8585} "com.example.feign.consumer.controller.FeignController.test(FeignController.java:22)"
44 = {StackTraceElement@8586} "sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)"
45 = {StackTraceElement@8587} "sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)"
46 = {StackTraceElement@8588} "sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)"
47 = {StackTraceElement@8589} "java.lang.reflect.Method.invoke(Method.java:498)"
48 = {StackTraceElement@8590} "org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)"
49 = {StackTraceElement@8591} "org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)"
50 = {StackTraceElement@8592} "org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)"
51 = {StackTraceElement@8593} "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)"
52 = {StackTraceElement@8594} "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)"
53 = {StackTraceElement@8595} "org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)"
54 = {StackTraceElement@8596} "org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)"
55 = {StackTraceElement@8597} "org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)"
56 = {StackTraceElement@8598} "org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)"
57 = {StackTraceElement@8599} "org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)"
58 = {StackTraceElement@8600} "javax.servlet.http.HttpServlet.service(HttpServlet.java:626)"
59 = {StackTraceElement@8601} "org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)"
60 = {StackTraceElement@8602} "javax.servlet.http.HttpServlet.service(HttpServlet.java:733)"
61 = {StackTraceElement@8603} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)"
62 = {StackTraceElement@8604} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
63 = {StackTraceElement@8605} "org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)"
64 = {StackTraceElement@8606} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
65 = {StackTraceElement@8607} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
66 = {StackTraceElement@8608} "org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)"
67 = {StackTraceElement@8609} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
68 = {StackTraceElement@8610} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
69 = {StackTraceElement@8611} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
70 = {StackTraceElement@8612} "org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)"
71 = {StackTraceElement@8613} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
72 = {StackTraceElement@8614} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
73 = {StackTraceElement@8615} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
74 = {StackTraceElement@8616} "org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)"
75 = {StackTraceElement@8617} "org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)"
76 = {StackTraceElement@8618} "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)"
77 = {StackTraceElement@8619} "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)"
78 = {StackTraceElement@8620} "org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)"
79 = {StackTraceElement@8621} "org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)"
80 = {StackTraceElement@8622} "org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)"
81 = {StackTraceElement@8623} "org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)"
82 = {StackTraceElement@8624} "org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)"
83 = {StackTraceElement@8625} "org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)"
84 = {StackTraceElement@8626} "org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)"
85 = {StackTraceElement@8627} "org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)"
86 = {StackTraceElement@8628} "org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)"
87 = {StackTraceElement@8629} "org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)"
88 = {StackTraceElement@8630} "org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)"
89 = {StackTraceElement@8631} "org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)"
90 = {StackTraceElement@8632} "java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)"
91 = {StackTraceElement@8633} "java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)"
92 = {StackTraceElement@8634} "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)"
93 = {StackTraceElement@8635} "java.lang.Thread.run(Thread.java:748)"

feign

SynchronousMethodHandler

首先在 SynchronousMethodHandler 通过反射调用 executeAndDecode() 发起请求。

如果执行正常,直接返回结果跳出循环,否则异常被捕获到,重试次数达到最大值后直接抛出异常跳出循环。

分为三个部分

第一部分

将每次请求时将请求计数重置

第二部分

正常执行返回跳出循环

第三部分

请求异常后重试处理,重试次数达到最大值后直接抛出异常跳出循环

将 IOException 包装到 FeignException

通过类的层次图,可以知道,SocketTimeoutException 是 IOException 的子类

spring-cloud-openfeign

LoadBalancerFeignClient

负责将 feign 原生调用转换为负载均衡调用

将 ClientException 转换为 IOException

ribbon

主要负责负载均衡处理,是客户端侧的实现。从服务注册的单个服务里找到匹配的实例进行调用。

AbstractLoadBalancerAwareClient

内层请求异常返回原始异常,外层异常使用 ribbon 的 ClientException 进行包装

最终通过 feign.Client.Default 来执行实际请求,如果引入了其他依赖(例如 feign-httpclient 或者 feign-hc5 或者 feign-okclient),会使用其他方式。

最终通过 native 函数调用 jvm 层次的 tcp 网络调用,出现异常返回 IOException。

可知,针对 feign 请求过程中出现异常无论如何返回的是 IOException,最终在 feign 的处理下包装为 FeignException。

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

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

相关文章

Java --- springcloud之consul

目录 一、consul的使用 1.1、主要功能 1.2、安装及运行 1.3、添加微服务到consul 1.3.1、8001微服务添加相关pom、配置文件、注解 1.3.2、80微服务添加相关pom、配置文件、注解 1.4、三个注册中心异同 1.5、consul进行分布式配置 1.5.1、修改8001的yml配置文件 1.5.2…

运维知识点-Apache HTTP Server

Apache 介绍 介绍 Apache是一个开源的Web服务器软件,全称为Apache HTTP Server,由Apache软件基金会开发和维护。它是目前全球使用最广泛的Web服务器软件之一,占全球所有网络服务器的很大比例。Apache服务器具有跨平台的特性,可以…

最简k8s部署(AWS Load Balancer Controller使用)

问题 我需要在k8s集群里面部署springboot服务,通过k8s ingress访问集群内部的springboot服务,应该怎么做? 这里假设已经准备好k8s集群,而且也准备好springboot服务的运行镜像了。这里我们将精力放在k8s服务编排上面。 一图胜千言…

基于Springboot的智慧社区居家养老健康管理系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的智慧社区居家养老健康管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)…

Humanoid-Gym 开源人形机器人端到端强化学习训练框架!星动纪元联合清华大学、上海期智研究院发布!

系列文章目录 前言 Humanoid-Gym: Reinforcement Learning for Humanoid Robot with Zero-Shot Sim2Real Transfer GitHub Repository: GitHub - roboterax/humanoid-gym: Humanoid-Gym: Reinforcement Learning for Humanoid Robot with Zero-Shot Sim2Real Transfer 一、介…

[java基础揉碎]super关键字

super关键字: 基本介绍 super代表父类的引用,用于访问父类的属性、方法、构造器 super给编程带来的便利/细节 1.调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类的属性由子类初始化) 2.当子类中有和父类中的成员(属性和方法)重…

软考高级:信息系统生命周期概念和例题

作者:明明如月学长, CSDN 博客专家,大厂高级 Java 工程师,《性能优化方法论》作者、《解锁大厂思维:剖析《阿里巴巴Java开发手册》》、《再学经典:《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

SpringCloudGateway网关限流

文章目录 令牌桶算法原理Gateway中限流实现 网关除了请求路由、身份验证,还有一个非常重要的作用:请求限流。当系统面对高并发请求时,为了减少对业务处理服务的压力,需要在网关中对请求限流,按照一定的速率放行请求。 …

【数据结构】单链表的层层实现!! !

关注小庄 顿顿解馋(●’◡’●) 上篇回顾 我们上篇学习了本质为数组的数据结构—顺序表,顺序表支持下标随机访问而且高速缓存命中率高,然而可能造成空间的浪费,同时增加数据时多次移动会造成效率低下,那有什么解决之法呢&#xff…

VS Code引入ECharts

Charts是一个使用 JavaScript 实现的开源可视化库,涵盖各行业图表,提供了丰富的图表类型和交互能力。(摘自菜鸟教程) 下面我们来介绍一下VS Code引入ECharts的相关操作 检查电脑是否已经安装了Java语言的软件开发工具包 ECharts…

设计模式-行为型设计模式-命令模式

命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。[DP] // 命令接口 interface Command {void execute(); }// 具体命…

备考银行科技岗刷题笔记(持续更新版)

银行考试计算机部分复习 IEEE 802.11的帧格式 1.1 IEEE 802.11是什么? 802.11是国际电工电子工程学会(IEEE)为无线局域网络制定的标准。目前在802.11的基础上开发出了802.11a、802.11b、802.11g、802.11n、802.11ac。并且为了保证802.11更…

java SSM售后服务管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

源码特点 java SSM售后服务管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代 码和数据库,系统主要采用B/…

Scrapy与分布式开发(2.3):lxml+xpath基本指令和提取方法详解

lxmlxpath基本指令和提取方法详解 一、XPath简介 XPath,全称为XML Path Language,是一种在XML文档中查找信息的语言。它允许用户通过简单的路径表达式在XML文档中进行导航。XPath不仅适用于XML,还常用于处理HTML文档。 二、基本指令和提取…

自编C++题目——几点了 hard ver.

题目难度 普及- 题目描述 一个老外用一口不流利的中文问你:“Xian zai ji dian le?”你看了一眼表,知道了现在是,你准备用这样的形式写在纸上: Now is m past/to h. 如果你看不懂,举个例子: 当h10&…

Rollup Summer:一览 Rollup 生态全景图

作者:Stanley,Kernel Ventures 编译:JIN,Techub News 短短几天内,ZKFair 的总锁定价值(TVL)已达到 1.2 亿美元,目前稳定在 8000 万美元,使其成为增长最快的 Rollup 之一…

SHARE 100M PRO:航测领域的多面手

在无人机航测领域,SHARE 100M PRO单镜头航测相机以其1.02亿像素的中画幅传感器和创新技术,正在重塑倾斜摄影的精度和效率。这款相机不仅在城市规划和土地管理中发挥着重要作用,还在环境监测、基础设施建设、农业管理等多个航测领域展现出其卓…

sheng的学习笔记-AI-多分类学习:ECOC,softmax

目录:sheng的学习笔记-AI目录-CSDN博客 基本术语: 若我们欲预测的是离散值,例如“好瓜”“坏瓜”,此类学习任务称为“分类”(classification); 若欲预测的是连续值,例如西瓜成熟度0.95、0.37,…

软考69-上午题-【面向对象技术2-UML】-关系

一、关系 UML中有4种关系: 依赖;关联;泛化;实现。 1-1、依赖 行为(参数),参数就是被依赖的事物,即:独立事物。 当独立事物发生变化时,依赖事务行为的语义也…

js【详解】原型 vs 原型链

原型 每个 class 都有显示原型 prototype每个实例都有隐式原型_proto_实例的_proto_指向对应 class 的 prototype 如下范例: class Student 创建了 实例 xialuo 获取属性 xialuo.name 或执行方法 xialuo.sayhi()时,先在自身属性和方法寻找&#xff0…