負(fù)載均衡關(guān)于請求頭的那些事


title: 負(fù)載均衡關(guān)于請求頭的那些事
date: 2022/07/21 13:58


本地環(huán)境

瀏覽器/客戶端(127.0.0.1)

# 訪問 nginx
curl localhost:8002/main/dqPlow/rest/async/req

nginx(192.168.2.43:8002)

server {
  listen       8002;
  server_name  localhost;
  
    location / {
        proxy_pass http://192.168.2.50:9999;

        proxy_set_header X-Forwarded-Host $http_host;  
        proxy_set_header X-Forwarded-Port  $server_port;
        proxy_set_header X-Real-IP $remote_addr;          
        proxy_set_header X-Forwarded-Proto  $scheme;                 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        root   html;
        index  index.html index.htm;
    }
}

gateway(192.168.2.50:9999)

spring:
  cloud:
    gateway:
      routes:
        - id: dqPlow
          uri: http://192.168.2.50:8080
          predicates:
            - Path=/main/dqPlow/**
          filters:
            - StripPrefix=1

dpPlow(192.168.2.50:8080)

請求頭變化

nginx gateway 請求頭 nginx 代理后(gateway 接收到的請求頭信息) gateway 代理后(應(yīng)用服務(wù)接收到的請求頭信息)
x-forwarded-proto http http,http
x-forwarded-host localhost:8002 localhost:8002,192.168.2.50:9999
x-forwarded-for 127.0.0.1 127.0.0.1,192.168.2.43
x-forwarded-port 8002 8002,9999
x-forwarded-prefix 未配置前綴 /main
forwarded 未配置 proto=http;host="192.168.2.50:9999";for="192.168.2.43:10593"
x-real-ip 127.0.0.1 127.0.0.1
host 192.168.2.50:9999 192.168.2.50:8080
  • x-forwarded-proto:標(biāo)識客戶端(瀏覽器或其他負(fù)載均衡器)用于連接到負(fù)載均衡器的實(shí)際協(xié)議虫啥。

  • x-forwarded-host:【客戶端調(diào)用服務(wù)端所使用的 ip:port】標(biāo)識客戶端(瀏覽器或其他負(fù)載均衡器)用于連接到負(fù)載均衡器的 ip:port

  • x-forwarded-for:【客戶端 ip】在客戶端訪問服務(wù)器的過程中如果需要經(jīng)過 HTTP 代理或者負(fù)載均衡服務(wù)器,可以被用來獲取最初發(fā)起請求的客戶端的 IP 地址垂攘。

    • 格式:X-Forwarded-For: <client>, <proxy1>, <proxy2>
    • <client>:客戶端的 IP 地址肺缕。
    • <proxy1>, <proxy2>:如果一個請求經(jīng)過了多個代理服務(wù)器砚作,那么每一個代理服務(wù)器的 IP 地址都會被依次記錄在內(nèi)暮顺。也就是說邓嘹,最右端的 IP 地址表示最近通過的代理服務(wù)器辖所,而最左端的 IP 地址表示最初發(fā)起請求的客戶端的 IP 地址恨课。
  • x-forwarded-port:標(biāo)識客戶端(瀏覽器或其他負(fù)載均衡器)用于連接到負(fù)載均衡器的端口號舆乔。

  • x-forwarded-prefix:負(fù)載均衡服務(wù)器代理服務(wù)的前綴

  • 注:上面這幾個頭部不屬于任何一份既有規(guī)范,但是他們已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn)剂公;關(guān)于負(fù)載均衡請求頭的標(biāo)準(zhǔn)版本是 Forwarded.

  • forwarded:感覺是一個沒用起來的規(guī)范

  • 注:下面這倆可以用希俩,但是不咋建議用

  • x-real-ip:【nginx 專屬】客戶端真實(shí) ip,與 x-forwarded-for中的是一樣的

  • host:負(fù)載均衡器調(diào)用服務(wù)使用的 ip:port

纲辽?颜武? 請求頭難道不區(qū)分大小寫嗎

HTTP報頭的名稱是不區(qū)分大小寫贫母,根據(jù)RFC 2616:每個標(biāo)題字段由一個名字后跟一個冒號(“:”)和字段值組成。字段名稱不區(qū)分大小寫(字段值可能區(qū)分大小寫盒刚,也可能不區(qū)分大小寫)腺劣。

注 1:所以 dqPlow 想要獲取用戶訪問的地址的話應(yīng)該這樣拼接:

x-forwarded-proto[0] + :// + x-forwarded-host[0] + x-forwarded-prefix[0...n] + server.servlet.context-path + 拼接自己的路徑

注2:如果在 nginx 中不配置那些 header,調(diào)用時dqPlow 服務(wù)接收到的請求頭是這樣的因块。

|-forwarded : proto=http;host="192.168.2.50:9999";for="192.168.2.43:9889"
|-x-forwarded-for : 192.168.2.43
|-x-forwarded-proto : http
|-x-forwarded-prefix : /main
|-x-forwarded-port : 9999
|-x-forwarded-host : 192.168.2.50:9999

注3:在spring體系中橘原,可以使用 ForwardedHeaderFilter 來處理此事務(wù),它是1個 filter 層的過濾器涡上,將會讀取 X-Forwarded- 層的頭信息趾断,并重新設(shè)置在 相應(yīng)的 request.getXXX 方法上,那么在業(yè)務(wù)端通過上述這些方法即能拿到正確的數(shù)據(jù)吩愧。 同時芋酌,此過濾器也將隱藏X-Forwarded- 這些請求頭,請求信息就像直接從瀏覽器發(fā)過來的一樣的雁佳。這樣一方面避免業(yè)務(wù)端來手動地處理這些請求脐帝,另一方面也避免業(yè)務(wù)端再次讀取這些X-頭,然后進(jìn)行二次處理糖权。

ForwardedHeaderFilter 過濾器并沒有默認(rèn)啟動堵腹,業(yè)務(wù)端需要顯示地進(jìn)行啟用。

需要注意的是星澳,spring容器中有1個組件 UriComponentsBuilder疚顷,以及 ServletUriComponentsBuilder,其內(nèi)部使用了跟 ForwardedHeaderFilter 一樣的邏輯禁偎,但是隨著版本的變更腿堤,其實(shí)際邏輯可能就跟 ForwardedHeaderFilter 邏輯不一致的。因此如暖,在沒有啟用 ForwardedHeaderFilter 的場景中笆檀,請先確保 spring 的版本與當(dāng)前業(yè)務(wù)期望行為一致。如 spring 5.0.X ServletUriComponentsBuilder 會讀取 X-Forwarded-Prefix 頭装处,但spring 5.1.X 就不再處理误债。其在官方的注釋上也寫得清楚浸船,如下

<p><strong>Note:</strong> As of 5.1, methods in this class do not extract``{@code "Forwarded"} and {@code "X-Forwarded-*"} headers that specify the``client-originated address. Please, use``{@link org.springframework.web.filter.ForwardedHeaderFilter``ForwardedHeaderFilter}, or similar from the underlying server, to extract``and use such headers, or to discard them.

<p><strong>注意:</strong>從 5.1 開始妄迁,此類中的方法不提取指定客戶端發(fā)起的地址。請使用``{@link org.springframework.web.filter.ForwardedHeaderFilter``ForwardedHeaderFilter} 或來自底層服務(wù)器的類似內(nèi)容李命,以提取``并使用此類標(biāo)頭登淘,或丟棄它們。

并且有特定的 https://github.com/spring-projects/spring-hateoas/issues/862 與之掛接.

在實(shí)際業(yè)務(wù)中封字,如果沒有 啟用 ForwardedHeaderFilter黔州,但想要拿到正確的請求信息耍鬓,建議自己參照 ForwardedHeaderFilter中的類 ForwardedHeaderExtractingRequest,處理好信息流妻,產(chǎn)生uri對象之后牲蜀,再通過 UriComponentsBuilder#fromUri 來拼接地址信息。

參考文章

使用X-Forwarded-*正確處理瀏覽器端地址信息

X-Forwarded-For

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绅这,一起剝皮案震驚了整個濱河市涣达,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌证薇,老刑警劉巖度苔,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浑度,居然都是意外死亡寇窑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門箩张,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甩骏,“玉大人,你說我怎么就攤上這事先慷『崧” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵熟掂,是天一觀的道長缎浇。 經(jīng)常有香客問我,道長赴肚,這世上最難降的妖魔是什么素跺? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮誉券,結(jié)果婚禮上指厌,老公的妹妹穿的比我還像新娘。我一直安慰自己踊跟,他們只是感情好踩验,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著商玫,像睡著了一般箕憾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拳昌,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天袭异,我揣著相機(jī)與錄音,去河邊找鬼炬藤。 笑死御铃,一個胖子當(dāng)著我的面吹牛碴里,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播上真,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼咬腋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了睡互?” 一聲冷哼從身側(cè)響起帝火,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎湃缎,沒想到半個月后犀填,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗓违,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年九巡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹂季。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡冕广,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出偿洁,到底是詐尸還是另有隱情撒汉,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布涕滋,位于F島的核電站睬辐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宾肺。R本人自食惡果不足惜溯饵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锨用。 院中可真熱鬧丰刊,春花似錦、人聲如沸增拥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掌栅。三九已至秩仆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渣玲,已是汗流浹背逗概。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留忘衍,地道東北人逾苫。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像枚钓,于是被迫代替她去往敵國和親铅搓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容