午休完上班後,同事說測試站點訪問介面出現400 Bad Request Request Header Or Cookie Too Large提示,心想還好是測試伺服器出現問題,影響不大,不過也趕緊上伺服器進行測試查看,打開nginx與ugwsi日誌與配置,發現後端服務日誌記錄正常,而測試站點的訪問日 ...
午休完上班後,同事說測試站點訪問介面出現400 Bad Request Request Header Or Cookie Too Large提示,心想還好是測試伺服器出現問題,影響不大,不過也趕緊上伺服器進行測試查看,打開nginx與ugwsi日誌與配置,發現後端服務日誌記錄正常,而測試站點的訪問日誌有7百多M(才運行兩三天沒幾個訪問,幾M的話才是正常現象),在瀏覽器里直接訪問後端服務介面也正常沒有問題(我們的伺服器軟體架構是微服務架構,將很多模塊分拆後分別部署,前端是一個純HTML站點,通過AJAX訪問後端各個服務,由於訪問量不大,所以前端站點的nginx配置時,做了反向代理訪問後端其他服務,這樣就不會出現跨域和需要處理多子功能變數名稱事情——即訪問不同的服務時,只需要使用當前功能變數名稱就可以了,這樣前端開發人員不必要知道後端掛載了多少服務需要使用什麼對應的功能變數名稱訪問)。訪問這台伺服器上的其他站點都能正常訪問,而問題站點的html頁面也能正常打開......在測試過程中發現,每訪問一下問題介面,訪問日誌就增加30多M,刷了幾次,nginx日誌大小直線上升......
由於日誌比較大,只能使用tail -n 5000 xxx_access.log >> xxx.log截取一下最新的日誌記錄下載下來,打開一看發現同一時間一個訪問,生產了2000多條重覆迴圈的訪問記錄,而日誌尾部$http_x_forwarded_for部分,有規律的存儲了相同的由多到少的IP字串,即:最後一條有一個IP字串(真實IP),倒數第二條有兩個IP字串(真實IP + 伺服器本地IP),倒數第三條有三個IP字串(真實IP + 兩個伺服器本地IP),以至類推
百度了一下“400 Bad Request Request Header Or Cookie Too Large”,查找出來的幾乎都是說“nginx 400 Bad request是request header過大所引起,request過大,通常是由於cookie中寫入了較大的值所引起。在nginx.conf中,將client_header_buffer_size和large_client_header_buffers都調大後可解決”,一看就知道這肯定不是我這種情況的解決辦法,這是由於不知道什麼原因引起的死迴圈將IP地址串寫入請求頭,直到緩存爆了才返回400,如果將緩存設置更大,只會造成日誌增加速度變大而已。從分析來看應該是nginx出現的問題。
沒有辦法只能在打開nginx配置文件分析,問題站點的配置文件,如下圖,並沒有發現什麼問題
打開nginx.conf進行慢慢研究,發現多了幾行代碼
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
這是用來將當前訪問用戶的IP傳給後端伺服器用的,將它們刪除重新啟動一下伺服器nginx後測試了一下,發現能正常訪問了...o my god,再將它放回去,重啟,訪問,掛了,去掉,重啟,訪問,正常......重試了好幾次,終於確定就是突然多出來的幾行代碼引起的。(後來問了一下同事才知道是他進伺服器添加的)
難道真的是不能使用嗎?記得以前用過還是正常的。嘗試訪問預生產環境介面,正常。打開預生產環境的nginx配置,包函有這三行代碼,如下圖
全面對比後發現,生產環境用的nginx配置是功能變數名稱,而預生產環境用的是IP+埠,除此之外沒有任何區別,使用跳轉方式與反向代碼方式測試,結果都是一樣,添加port_in_redirect、server_name_in_redirect配置也沒能解決
綜合分析,應該是nginx在使用proxy_pass做跳轉時,如果直接使用功能變數名稱,且需要向後端提交當前訪問的IP地址時,引發nginx的bug造成死迴圈,不知道大家有沒有遇到過這種情況。
# 使用反向代理方式
# 正常的配置 upstream xxx{ server 127.0.0.1:23456; } upstream yyy { server 127.0.0.1:123455; } # 異常配置 upstream xxx1{ server xx.xxx.com; } upstream yyy2 { server yyy.xxx.com; }
# 使用跳轉方式 # 正常配置 proxy_pass http://127.0.0.1:23456; # 異常配置 proxy_pass http://xx.xxx.com;
版權聲明:
本文由AllEmpty原創併發布於博客園,版權與博客園共同所有,歡迎轉載,未經本人同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利。如有問題,可以通過[email protected] 聯繫我,非常感謝。
發表本編內容,主要是為了和大家共同學習共同進步,有興趣的朋友可以加加Q群:327360708 ,大家一起探討。
更多內容,敬請觀註博客:http://www.cnblogs.com/EmptyFS/