Nginx 转发时的一个坑,运维竟然让我背锅!!

最近遇到一个 Nginx 转发的坑,一个请求转发到 Tomcat 时发现有几个 http header 始终获取不到,致使线上出现 bug,运维说不是他的问题,这个锅我背了。java

新增的几个 header 是这样的:nginx

  • accept_sign
  • accept_token
  • ...

反复检查代码,肯定这些 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 的官方说明:

https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/?highlight=underscores#missing-disappearing-http-headers

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 写了一段逻辑,同事直呼看不懂,你试试看。。

4.吊打 Tomcat ,Undertow 性能很炸!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

以为不错,别忘了随手点赞+转发哦!

相关文章
相关标签/搜索