当前位置:   article > 正文

超详细 openFeign 踩坑解决过程_openfeign 捕获异常 统一处理

openfeign 捕获异常 统一处理

问题

这里前提是你已经根据官网或者其他视频教程初步搭建了openFeign的环境,但是运行过程中踩坑到了一些问题汇总。我花了一晚上时间才终于成功解决。

  1. 项目中存在统一返回响应对象,例如 R<>
  2. 调用超时问题
  3. 微服务传递过程中,需要携带header-token,但获取不到request

解决

1. 这里我实际上是debug最久的一次,每次回调都是null,需要在feign中加入R<>
// R<> 是我自定义的一个全局统一返回对象, 
@Data
public class R<T> implements Serializable {
    /** 错误码 */
    private Integer code;

    /** 错误消息 */
    private String message;

    /** 泛型响应数据 */
    private T data;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
/// 需要被调用的服务中心方法,by orange-authority
@PostMapping("/token")
public JwtToken token(@RequestBody UsernameAndPassword usernameAndPassword)
        throws Exception{
    log.info("request to get token with param: [{}]",
            JSONUtil.toJsonStr(usernameAndPassword));
    String token = orangeUserService.generateToken(usernameAndPassword.getUsername(), usernameAndPassword.getPassword(), true);
    return new JwtToken(token);
}

/// feign-client 中需要加入R<>,  by orange-nacos-client
@FeignClient(
        contextId = "AccountFeignClient", value = "orange-spring-service-account",
        fallbackFactory = AccountFeignClientFallbackFactory.class
)
public interface AccountFeignClient {

    @GetMapping("/orange-spring-service-account/account/get-user-info-by-id")
    public R<UserInfo> getUserInfoById(@RequestParam Long id);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
2. 超时问题,

以下是我个人理解,如有错误还望指出:

因为Feign是基于Ribbon, 至于为什么同时要设置hystrix and ribbon 的超时时间呢?因为ribbon重试机制, 当超出总时间上限 Hystrix熔断, 下面是我的配置信息,可以参考一下

# Feign 的相关配置

#ribbon
ribbon:
  # ribbon 的超时时间
  ConnectTimeout: 1000
  ReadTimeout: 1000
#  OkToRetryOnAllOperations: true
#  MaxAutoRetries: 1
#  MaxAutoRetriesNextServer: 1

# 全局指定 hystrix 默认配置
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            #断路器超时时间
            timeoutInMilliseconds: 5000
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
3. 如果你的token是放在header中,并且调用时发现token传递不过去
  1. 使用 RequestInterceptor 完成一个类似拦截器的功能
  2. 获取 request,这个从上下文拿到,就是你本身的request
  3. 在 request 中拿到header,并且写入 restTemplate 中的header (也可以直接传入单个token)
  4. 然后发现获取不到当前上下文,因为 Hystrix 默认设置线程池隔离策略,这里我使用信号量隔离策略,希望评论区有大佬能改善这步
@Slf4j
@Configuration
public class FeignConfig {

    @Bean
    public RequestInterceptor headerInterceptor() {

        return template -> {

            ServletRequestAttributes attributes =
                    (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (null != attributes) {
                HttpServletRequest request = attributes.getRequest();
                Enumeration<String> headerNames = request.getHeaderNames();
                if (null != headerNames) {
                    while (headerNames.hasMoreElements()) {
                        String name = headerNames.nextElement();
                        String values = request.getHeader(name);
                        template.header(name, values);
                    }
                }
            }
        };
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
hystrix:
  command:
    default:
      execution:
        isolation:
          # 线程池隔离策略
#          strategy: THREAD
          # 线程池信号量隔离策略
          strategy: SEMAPHORE
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 完成
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/84593
推荐阅读
  

闽ICP备14008679号