feign 使用时可能的问题
1、请求地址不对
此时调用的时候会报 404。这个时候就要检查下是不是接口定义的地址和其实现的地址是否一致,这个应该是比较好排查的
2、content-type 问题
https://github.com/OpenFeign/feign/issues/1723
可以参照这个问题,其也会报 404
3、服务找不到
当我们使用 name 或者 value 来指定我们的服务名的时候,可能会报服务找不到的问题。这个时候可以通过指定 url 的方式,如果指定 url 依然不行,那么说明目标服务不存在。
@FeignClient(
value = "my-service-server",
url = "http://my-service-server",
path = "/xxx",
contextId = "xxx")
当 value 和 url 都存在时,优先使用 url
4、循环调用
A -> B -> A。
就是 A 服务调用 B 服务的接口,在 B 服务中再调用 A 服务的接口。这个时候如果 B -> A 的时候出现 404,可能是因为请求头设置有问题。可以通过增加日志来定位
feign:
client:
config:
default:
loggerLevel: full
logging:
level:
com.client.*: debug // 服务端提供的接口的路径
在配置中增加这个配置,就可以打印出 feign 调用时的请求参数以及请求头。
当获取到 feign 调用的请求头和请求参数之后,可以尝试使用 curl 的方式去请求接口,带上 feign 调用时的请求头和请求参数,看看是否也是 404。如果是的,这个时候可以通过调整请求头和请求参数来消除 404。这个时候你就可以知道到底是请求头不对还是请求参数不对。
针对请求头不对的场景,可能是由于 RequestInterceptor 这个接口导致的。
在使用 feign 的时候,我们有时候可能会自定义 RequestInterceptor 来在 feign 调用的时候设置一些参数,比如请求头,这可能就是导致 404 的主要原因。
在 RequestInterceptor 定义的时候切记不要将其注册到 spring 容器中(比如增加 @Configuration 注解),这样会导致当前这个RequestInterceptor 会作用于所有的 feignClient 上。 如果你想要在 feignClient 上使用 RequestInterceptor ,可以通过 FeignClient 这个注解的 configuration 来指定。
@FeignClient(
value = "my-service-server",
url = "http://my-service-server",
path = "/xxx",
contextId = "xxx",
configuration = {xxx.class})
我遇到的场景是,有一个全局的 RequestInterceptor ,其会进行请求头的复制。就是在 A -> B -> A 的场景下,当 B -> A 的时候,其会将 A -> B 的请求头复制过来,作为 B -> A 的请求头。在这些请求头中,有一个比较特殊的请求头 Host
。Host 表示的是目标服务的地址,