今天遇到了一个巨坑---关于feign的---如果你有使用feign出现了超时报错,报null,404--请进来看一看

前言

今天确实遇到了一个巨坑啊·!
搞了很久。

本来错误的原因也很简单
但是feign 开起了hystrix报错

feign:
  hystrix:
    enabled: true

就一直给我报这个两个错误

错误

报错一:

在这里插入图片描述
连接时间超时,看到这个我就想到,肯定是hystrix配置出问题了
可是原来的配置没问题啊,对于超时,已经处理了,看一下原来的配置

#超时配置
ribbon:
  ReadTimeout: 300000

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000
        timeout:
          enabled: false

不死心的我去网上找了找,发现这个的处理都是和我一样的啊!

但是找着突然看到,嗯?有希望马上去改

ConnectTimeout: 300000

我觉得应该是了,没问题。
但是下一刻,我的心态有点炸。。。。

第二个报错

在这里插入图片描述

null 这个有点蒙啊?这是什么错
想了半天也没有解决

怎么办?突然想到把 hystrix关了吧。虽然这个指标不治本,但应该行

feign:
  hystrix:
    enabled: false

继续尝试

有报错了,不过这个报错然我彻底知道为什么了

最后一个报错

在这里插入图片描述
这是什么?
通过注解

@FeignClient(value = "goods")
//name 也是一样的

生成的地址是错误的。
我开始检查eureka服务-----没问题
在这里插入图片描述
检查spring.application.name的名字 -----没问题

没办法了
我看了一下注解的源码,发现他还有url属性,了解一下,这个注解可以指定路径

最后

@FeignClient(value = "goods" ,url = "http://localhost:9011")

成功了。。。。。
(很烦开启了hystrix,抛出的错误信息一致误导我)
但是为什么会这样,原因还没找到。看看有没有路过的大神说一下原因。

今天 突然发现只要把hystrix关了 ,就能实现了??? 一头雾水

解决了

问题原因:

在feign调用之前,我给他开启了一个拦截器 RequestInterceptor实现类
里面有使用到ServletRequestAttributes 获取请求数据

当feign开启熔断模式的时候,feign 调用会失败 (feign: hystrix: enabled: true)

原因:feign 使用的是线程池模式,当开启熔断的时候,feign 所在的服务端不在同一个线程,这是attributes取到的将会是空值

以下 拦截器代码

public class FeignInterceptor implements RequestInterceptor {

    /**
     * feign执行之前拦截
     * @param requestTemplate
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
        try {
          
            //使用RequestContextHolder工具获取request相关变量
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes != null) {
                //取出request
                HttpServletRequest request = attributes.getRequest();

                //获取所有头文件信息的key
                Enumeration<String> headerNames = request.getHeaderNames();
                if (headerNames != null) {
                    while (headerNames.hasMoreElements()) {
                        //头文件的key
                        String name = headerNames.nextElement();
                        //头文件的value
                        String values = request.getHeader(name);
                        System.out.println("头信息=========="+ name+ ":" + values );
                        //将令牌数据添加到头文件中
                        requestTemplate.header(name, values);
                    }
                }


            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

解决方案:将hystrix熔断方式: 线程模式改为信号量模式

配置:

feign:
  hystrix:
    enabled: true
#hystrix 配置
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000
          strategy: SEMAPHORE

线程一信号量隔离区别

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43157543/article/details/104887219