最近遇到一個 Nginx 轉發的坑,一個請求轉發到 Tomcat 時發現有幾個 http header 始終獲取不到,致使線上出現 bug,運維說不是他的問題,這個鍋我背了。java
新增的幾個 header 是這樣的:nginx
反覆檢查代碼,肯定這些 header 是傳了的,並且本地測試單獨在 tomcat 中是能夠接受到這些參數的,因此 tomcat 和命名自己是沒問題的,初步判定是 Nginx 的問題。spring
通過一翻搜索,終於找到了一個 Nginx 的配置參數:underscores_in_headers,這個參數默認值爲:off,即默認忽略帶下劃線的 header。tomcat
解決方案:intellij-idea
一、在 http 或者 server 配置中把 underscores_in_headers 配置參數開關打開:app
server { ... underscores_in_headers on; ... }
增長配置後,而後重啓 Nginx。運維
二、使用破折號(-)代替下劃線(_),或者統一規範直接不要使用下劃線;ide
咱們來看下通常的 http header 長什麼樣的:spring-boot
通常所見的 headers 確實也都是中槓線,沒有下劃線。性能
Nginx 爲何默認忽略帶下劃線 header?
我找到了 Nginx 的官方說明:
If you do not explicitly set
underscores_in_headers on;
, NGINX will silently drop HTTP headers with underscores (which are perfectly valid according to the HTTP standard). This is done in order to prevent ambiguities when mapping headers to CGI variables as both dashes and underscores are mapped to underscores during that process.
根據官方說明,這樣作是爲了不把 headers 映射爲 CGI 變量時出現歧義,由於破折號和下劃線都會被映射爲下劃線,因此二者很差區分……
好吧,終於弄清楚了,這個問題也太變態了,這應該是 Nginx 設計時的一個缺陷吧,這個坑我替大家踩了!
因此,推薦你們使用第二種方案吧,統一規範 headers 不要使用下劃線,使用 Nginx 默認的配置便可,這樣能夠儘可能避免環境上的差別,以避免後續帶來問題。
@阿里Java開發手冊 是否考慮新增這條規範?
版權申明:本文系公衆號 "Java技術棧" 原創,原創實屬不易,轉載、引用本文內容請註明出處,禁止抄襲、洗稿,請自重,尊重他人勞動成果和知識產權。
近期熱文推薦:
1.Java 15 正式發佈, 14 個新特性,刷新你的認知!!
2.終於靠開源項目弄到 IntelliJ IDEA 激活碼了,真香!
3.我用 Java 8 寫了一段邏輯,同事直呼看不懂,你試試看。。
以爲不錯,別忘了隨手點贊+轉發哦!