前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nginx rewrite与proxy_pass配置问题分享

nginx rewrite与proxy_pass配置问题分享

作者头像
山行AI
发布2019-11-12 14:35:19
3.5K0
发布2019-11-12 14:35:19
举报
文章被收录于专栏:山行AI山行AI

websocket服务器在用http://localhost:8888/bbbb/websocket请求时总是报错,经过分析发现是nginx的问题,于是有了这篇文章。

nginx 的配置一

代码语言:javascript
复制
location /bbbb/websocket{
        rewrite ^/bbbb/websocket/(.*)$ /websocket/$1 break ;
        proxy_pass http://websocketbbbb/;
        proxy_connect_timeout 60;
        proxy_send_timeout  60;
        proxy_read_timeout 3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'Upgrade';

       }

请求一

  • 路径:https://abc.ddd.cn/bbbb/websocket
  • 请求方式:post
  • nginx 日志:
代码语言:javascript
复制
1.1.1.1 - - [07/Nov/2019:15:58:42 +0800] "POST /bbbb/websocket HTTP/2.0" 404 13 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"
  • 抓包信息:
代码语言:javascript
复制
POST / HTTP/1.1
Host: abc.ddd.cn
X-Real-IP: 1.1.1.1
REMOTE-HOST: 1.1.1.1
X-Forwarded-For: 1.1.1.1
Connection: Upgrade
Content-Length: 10
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36
cache-control: no-cache
origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
x-requested-with: XMLHttpRequest
accept-language: zh-CN,zh;q=0.9,en;q=0.8
postman-token: 17daff12-3bcc-4c1c-4c9f-2f5aebaa3cd5
content-type: application/x-www-form-urlencoded
accept: */*
sec-fetch-site: cross-site
sec-fetch-mode: cors
accept-encoding: gzip, deflate, br

6666666666HTTP/1.1 404 Not Found
content-length: 13

404 Not Found
  • 服务器输出:

结果为:

代码语言:javascript
复制
before request method is:POST    req uri is:/-[]

其他请求(请求方式不变)

  1. 请求路径:http://localhost:8888/bbbb/websocket/ 服务器输出:
代码语言:javascript
复制
before request method is:POST    req uri is://-[]
  1. 请求路径:http://localhost:8888/bbbb/websocket/aaa 服务器输出:
代码语言:javascript
复制
before request method is:POST    req uri is://aaaa-[]

分析

原因是 rewrite 规则没生效,因为把rewrite那一行去掉,重启nginx之后,各种请求呈现的结果无殊。同时我们需要注意的是proxy_pass的规则,当rewrite不生效时:

  • https://abc.ddd.cn/bbbb/websocket进入proxy_pass后会请求http://websocketbbbb/;
  • http://localhost:8888/bbbb/websocket/会请求http://websocketbbbb//
  • http://localhost:8888/bbbb/websocket/aaa会请求http://websocketbbbb//aaa

也就是与location匹配上之后多出的那一段都会加到proxy_pass后面。

关于proxy_pass更多的说明,参考下这篇文章:https://blog.csdn.net/ainuser/article/details/80260144 说明,这种情况下不会与rewrite规则匹配上,所以路径直接与proxy_pass匹配。

nginx 的配置二

代码语言:javascript
复制
location /bbbb/websocket/{
        rewrite ^/bbbb/websocket/(.*)$ /websocket/$1 break ;
        proxy_pass http://websocketbbbb/;
        proxy_connect_timeout 60;
        proxy_send_timeout  60;
        proxy_read_timeout 3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'Upgrade';

       }

第一种情况:

  • 请求路径:https://abc.ddd.cn/bbbb/websocket
  • 请求方式:POST
  • nginx 日志:
代码语言:javascript
复制
1.1.1.1 - - [07/Nov/2019:14:43:27 +0800] "POST /bbbb/websocket/ HTTP/2.0" 302 154 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

1.1.1.1 - - [07/Nov/2019:14:43:27 +0800] "GET /404.html HTTP/2.0" 200 754 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

第二种情况:

  • 请求路径:https://abc.ddd.cn/bbbb/websocket/
  • 请求方式:POST
  • nginx 日志:
代码语言:javascript
复制
1.1.1.1 - - [07/Nov/2019:14:44:19 +0800] "POST /bbbb/websocket HTTP/2.0" 301 178 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

1.1.1.1 - - [07/Nov/2019:14:44:23 +0800] "GET /bbbb/websocket/ HTTP/2.0" 302 154 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"
1.1.1.1 - - [07/Nov/2019:14:44:23 +0800] "GET /404.html HTTP/2.0" 200 754 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36"

问题分析

两种情况下均为 post 请求,可以看出,在第一种情况下请求被转换成了 GET,从而导致后台 websocket 服务报错。第二种情况正常工作。

原因在于location的路径为/bbbb/websocket/,而实际发送请求的路径为/bbbb/websocket,当请求匹配上时nginx会自动在后面添加一个目录/,然后进行重定向,关于这个问题,可以参考:https://www.cnblogs.com/zeoblog/p/6046144.html。也就是说这种情况下的匹配会有两步,先添加一层目录进行301重定向,然后再次匹配时路径是正确的,但是请求方式由post改成了get,从而导致后台服务报错。

注意,这个301不是rewrite引起的,break操作下的rewrite是不会重定向的。添加目录的操作是在location路径的最后一层匹配时发生的。对于get和post请求如果路径不正确时都会出现重定向的情况,只是post方式重定向后会变成get。 说明,这种情况下都会与rewrite规则匹配上,所以会先进行rewrite之后再将rewrite的结果加在proxy_pass上。

解决办法

配置修改为:

代码语言:javascript
复制
location /bbbb/{
        rewrite ^/bbbb/websocket/(.*)$ /websocket/$1 break ;
        proxy_pass http://websocketbbbb/;
        proxy_connect_timeout 60;
        proxy_send_timeout  60;
        proxy_read_timeout 3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'Upgrade';

       }

这种情况下,请求路径为/bbbb/websocket时会完全匹配location,不会再往路径后面添加/,不会先进行301重定向。

说明,这种情况下rewrite和proxy_pass都能正常工作,而且不会出现nginx自动添加一层目录的问题。

参考

  • http://nginx.org/en/docs/http/ngxhttpcoremodule.html#servernameinredirect
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发架构二三事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • nginx 的配置一
    • 请求一
      • 其他请求(请求方式不变)
        • 分析
        • nginx 的配置二
          • 第一种情况:
            • 第二种情况:
              • 问题分析
              • 解决办法
              • 参考
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档