当前位置:首页 > 技术文章 > 正文内容

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

arlanguage5个月前 (12-17)技术文章43

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

新增的几个 header 是这样的:

  • accept_sign
  • accept_token

反复检查代码,确定这些 header 是传了的,而且本地测试单独在 tomcat 中是可以接受到这些参数的,所以 tomcat 和命名本身是没问题的,初步断定是 Nginx 的问题。

经过一翻搜索,终于找到了一个 Nginx 的配置参数:underscores_in_headers,这个参数默认值为:off,即默认忽略带下划线的 header。

解决方案:

1、在 http 或者 server 配置中把 underscores_in_headers 配置参数开关打开:

server {
  ...
  underscores_in_headers on;
  ...
}

增加配置后,然后重启 Nginx。

2、使用破折号(-)代替下划线(_),或者统一规范直接不要使用下划线;

我们来看下一般的 http header 长什么样的:

一般所见的 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技术栈” 原创,原创实属不易,转载、引用本文内容请注明出处,禁止抄袭、洗稿,请自重,尊重他人劳动成果和知识产权。

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/274.html

分享给朋友:

“Nginx 转发时的一个坑,运维居然让我背锅” 的相关文章

使用 Nginx 部署 Java web 服务

比较早之前,部署 Java web 服务只是单纯使用 Tomcat 做 Web 服务器,前后端代码融合在一个工程之中。Tomcat 启动后对外提供一个端口接收和相应 http请求。随着 Nginx 得越来越流行,同时加上其优秀的反向代理和负载均衡功能,我们在线上的 Java web 通常会结合二者,...

【Nginx】Nginx 4种常见配置实例 nginx常用配置

本文主要介绍nginx 4种常见的配置实例。Nginx实现反向代理;Nginx实现负载均衡;Nginx实现动静分离;Nginx实现高可用集群;Nginx 4种常见配置实例如下:一、Nginx反向代理配置实例1.1 目标访问http://ip,访问到的是Tomcat的主页面http://ip:8080...

推荐一个Nginx配置文件的网站 nginx配置文件的几大模块

NGINX 不仅仅是一个 Web 服务器。你可能已经知道了。我们喜欢 NGINX,因为:内存使用率低高并发异步事件驱动架构负载均衡反向代理FastCGI 支持缓存 (PHP)静态文件的惊人快速处理使用 SNI 的 TLS/SSL特征:HTTPS、HTTP/2、IPv6、certbot、HSTS、安全...

nginx location 多root理解location

由于应用需求,这个 r 目录需要单独拉出来做处理,nginx 最开始是这样写的: server { root /home/webadm/htdocs; index index.php; location /r/ { root /diska/htdocs; } location ~ \.php { f...

一起学习Kubernetes:容器和镜像

简述容器每个运行的容器都是可重复的;包含依赖环境在内的标准,意味着无论你在哪里运行它都会得到相同的行为。容器将应用程序从底层的主机设施中解耦。 这使得在不同的云或 OS 环境中部署更加容易。Kubernetes 集群中的每个节点都会运行容器,这些容器构成分配给该节点的 Pod。 单个 Pod 中的容...

宝塔面板如何关闭https强制跳转http/https共存

宝塔面板如何关闭https强制跳转http/https共存在 宝塔面板 中,如果你需要关闭 HTTPS 强制跳转并实现 HTTP 和 HTTPS 共存,可以通过以下步骤完成配置:一、关闭 HTTPS 强制跳转登录宝塔面板进入宝塔后台,点击左侧菜单中的 网站。找到目标网站在网站列表中找到需要取消 HT...