SpringCloud Feign踩坑: 解决问题思路记录
一. 一分钟快速了解Feign
- 之前有提到过Feign的文章,同学们需要了解的,可以点开找到指定的讲解Feign的目录:
- 总结来说,Feign的功能就是远程调用,能够以一种比较优雅的方式去实现服务消费者对服务生产者的调用。
二. 踩了什么样的坑?
- 问题现象为:Feign一直调用失败,获取到的数据为null
- 代码展示:(Gradle+Kotlin项目、与Java+Maven可能语法稍有不同,实际相差不多的)
- 已引入Gradle依赖:
compile("org.springframework.cloud:spring-cloud-starter-openfeign")
- 已加上Feign的启动类注解:
- 已正确配置Feign:
- application.yml中开启Hystrix断路器:
- 调用接口调试:
- 已引入Gradle依赖:
- What?! 感觉配置的没有一点问题,可为什么查询返回来数据为空呢???下一章,博主带大家层层剖析,通过解决这个问题,去锻炼自己解决问题的思路!!
三. 解决问题!
3.1 分析为什么返回空?
- 首先,我们发现没有日志报错(划重点)。于是无法通过当我们看这个返回空的结构,说明是通过Page对象返回的,在我们的fallback中定义了空对象,如图所示:
3.2 通过FallbackFactory 获取错误日志
- 通过对Feign的学习可以知道,Fallback是无法获取错误信息的,所以就没有错误日志了。但是FallbackFactory可以获取到错误信息。于是,用FallbackFactory来代替Fallback:
3.3 定位Feign切面类问题,进行分析
- 通过打印错误日志,定位到了Feign发出请求之前,调用了Feign切面类,这个切面类的作用是携带用户Token。而这里报了空指针异常:
3.4 结合所学知识进行分析
- 当我们关闭断路器开关:
发现能够正常调用,能够正常返回列表数据:feign: httpclient: enabled: false
- 于是可以得出:
- Feign正常调用,没有问题
- 断路器发生异常,可能断路器出现了问题;
- 获取请求上下文失败,所以无法拿到Token
- 服务正常,仅仅是因为Token获取不到造成一直走fallback方法
3.5 根据断路器知识进行分析:
- 我们的配置断路器没有问题,为什么会获取失败呢??
- 突然灵光一现,断路器有线程隔离,而Spring获取请求上下文是通过LocalThread进行获取的,所以由于线程隔离,所以导致的Spring获取不到Token呢?
- 于是配置线程隔离规则,并开启断路器:
feign: hystrix: enabled: true hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 60000 strategy: SEMAPHORE
- 重新调用接口,发现成功获取到数据,Success!!
四. 解决问题思路总结:
- 先检查Feign配置是否正确
- 检查断路器配置是否正确
- 将Feign中的fallback替换为FallbackFactory,获取错误日志信息(知识点)
- 定位到异常后通过分析断路器的特点为线程隔离,导致获取不到请求上下文(知识点)
- 修改线程隔离策略,解决问题!