今天遇到了一個巨坑---關於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

線程一信號量隔離區別

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章