Feign远程服务无法调用问题解决

  1. 1. 报错信息1:
    1. 1.1. 原因:
    2. 1.2. 解决办法
  2. 2. 报错信息2:
    1. 2.1. 解决方法:
  3. 3. @FeignClient常用属性如下:

报错信息1:

Unauthorized 401

1
feign.FeignException$Unauthorized: [401] during [GET] to [http://user-service/2] [UserService#queryUserById(Long)]: []

原因:

Feign在进行远程调用时, 默认是没有将请求头继续往下传递的, 而系统微服务接入认证之后, 必须携带JWT令牌才可以访问, 没有携带令牌就访问系统服务, 就会出现401 , 未认证错误。

解决办法

使用Feign的拦截器来解决, 拦截所有的feign的远程调用, 在进行远程调用时, 拦截住请求, 并让请求头Authorization 继续往下传递。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
public class FeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(requestAttributes != null){
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String authorization = request.getHeader("Authorization");
template.header("Authorization", authorization);

}
}
}

报错信息2:

feign.FeignException$NotFound:
[404] during [GET] to [http://user-service/2] [UserService#queryUserById(Long)]: [{“timestamp”:”2022-10-07T11:13:45.296+00:00”,”status”:404,”error”:”Not Found”,”message”:””,”path”:”/2”}]

解决方法:

1
2
3
4
5
@FeignClient(
value = "user-service",
url = "http://localhost:7000/user-service/user",
fallbackFactory = UserServiceFallback.class
)

加了url,指定@FeignClient调用的地址问题解决

@FeignClient常用属性如下:

  • name/value:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
  • contextId:指定beanID
  • url: url一般用于调试,可以手动指定@FeignClient调用的地址
  • decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
  • configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
  • path: 定义当前FeignClient的统一前缀