记录: 一次Ngnix代理问题的排查

﹥>﹥吖頭↗ 提交于 2020-03-02 08:39:04

场景

网络访问关系图如下, PC浏览器需要访问到Tomcat的Web应用.

因为网络隔离, PC机所在的环境访问不了Nginx2, 所以加了一层Nginx1的网络代理. Ngnix1的简要配置如下:

server{
   listen 8888; 
   server_name 10.254.209.65;
   location / {
      proxy_pass http://10.254.213.149:80;
   }
}

 然后Nginx2代理了tomcat应用, 简要配置如下:

upstream tom {
  server ip:port;
}

server {
    listen       80;
    server_name  10.254.213.149;
    
    location /admin {
        proxy_pass http://tom/admin;
    }
}

问题

在PC浏览器上输入10.254.209.65:8888/admin/就可以正常显示tomcat的web页面, 而输入10.254.209.65:8888/admin 时就404, 后者比前者少了一个斜杠“/”而已.

排查

在PC浏览器输入10.254.209.65:8888/admin 时, 发现地址会莫名其妙地重定向为 10.254.209.65/admin/

重定向之后的地址有2处明显变化: 一是端口8888变成了80(默认不显示) ;  二是admin后面追加上了斜杠“/”.

似乎问题的根源还是斜杠“/”, 那就先从它入手.

Nginx不会自动追加斜杠“/”, 其配置文件里也没有显示去追加“/”, 于是开始怀疑到Tomcat.

切到Nginx2所在主机下, 不走代理, 通过curl直接访问Tomcat应用:

 curl -I http://tom/admin

显示信息如下

HTTP/1.1 302 
Location: http://tom/admin/

Transfer-Encoding: chunked
Date: Sun, 30 Dec 2018 13:24:35 GMT

确实发生了302重定向, 并且地址追加上了斜杠“/”.

想了想应用代码应该不会无故干这种事, 难道是Tomcat自己干的?

于是去看了一下Tomcat的access日志, 确实有一个302. 然后去网上查了一下资料, 大致就是说当Tomcat的应用带有contentPath的时候, 比如这里的/admin, 那么客户端访问时, 如果直接请求/admin的话, Tomcat就会自动重定向去追加斜杠变成/admin/.

到此, 我们似乎已经知道如何去解决问题了, 只要在Nginx2的proxy_pass地址后面显示加个“/”就行了, 如下:

proxy_pass http://tom/admin/;

这样/admin请求在Nginx2处转发时就会带上“/”, 然后Tomcat收到请求后就不会再重定向了.

验证一下, 在PC上输入10.254.209.65:8888/admin 确实访问正常了.

看似问题是解决了, 但是重定向端口号从8888变成了80还没有查明, 里面一定有坑.  

重定向不同于服务器内部转发, 重定向的指令是服务器发给客户端的, 当然应该使用客户端输入的IP和PORT.

继续分析, 这时产生了一个错觉: Tomcat在重定时拿到的端口号不对, 它只拿到了最近一个Nginx的端口, 即Nginx2的端口80, 而拿不到Nginx1的8888.

为什么说是错觉呢, 因为Tomcat其实根本不会去拿什么端口号,它只会拿当前Http请求的Head里面的Host信息.

为什么用Nginx这么久, 很少碰到这种端口问题, 因为一般用的端口是80, 而Nginx代理时Host的取值默认是$host, 相当于$host:80, 所以也就不会出问题.

在一些特殊场景出现非80端口时, 如果只有一层Nginx代理还好说, 可以在代理时设置Head转发后的Host值, 把端口带上, 如下

proxy_set_header Host $host:$server_port;

但是对于当前问题场景, 有2层Nginx代理, Nginx2无法直接拿到Nginx1的端口信息, 那怎么办呢?

目前能想到的方法, 就是在代理/admin下设置Host时, 把配置端口写死, 如下:

proxy_set_header Host $host:8888;

这样当Tomcat重定向时就没有问题了, 不过你得先知道客户端请求的端口是8888, 当其变化后也需要跟着同步.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!