美文网首页
nginx配置遇到的问题

nginx配置遇到的问题

作者: Martain | 来源:发表于2020-11-18 11:07 被阅读0次

nginx配置遇到的问题

问题一:转发后缀是否带斜杠的问题

接收测试服务

from flask import Flask, request, jsonify
from gevent import pywsgi
app = Flask(__name__)
app.debug = True
app.config['JSON_AS_ASCII'] = False

@app.before_request
def request_before(): 
    return success(request.path) 

def success(data = None):
    return response(0, "success",data)

def response(code, msg, data=''):
    return jsonify({'code': code, 'msg': msg, 'data': data})

if __name__ == "__main__":
    print("开始启动web服务器...")
    server = pywsgi.WSGIServer(('0.0.0.0', 9999), app)
    server.serve_forever()

这段代码直接监听9999端口,然后直接将请求的url返回,格式为:

{
  code:0,
  msg:"success",
  data:"path"
}

nginx 测试配置

 server {
        listen       999;
        server_name  localhost;
                # location 匹配带'/'后缀  proxy_pass url带 '/' 后缀
        location /prod-api/{
            proxy_set_header Host $http_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_pass http://localhost:9999/;
        }
                # location 匹配不带'/'后缀  proxy_pass url带 '/' 后缀
        location /dev-api {
            proxy_set_header Host $http_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_pass http://localhost:9999/;
        }
                # location 匹配带'/'后缀  proxy_pass url不带 '/' 后缀
        location /test-api/{
            proxy_set_header Host $http_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_pass http://localhost:9999;
        }
        
        # location 匹配不带'/'后缀  proxy_pass url不带 '/' 后缀
        location /api {
            proxy_set_header Host $http_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_pass http://localhost:9999;
        }

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        } 
    }

实测结果

[root@localhost ~]# curl http://localhost:999/prod-api/api
{
  "code": 0, 
  "data": "/api", 
  "msg": "success"
}
[root@localhost ~]# curl http://localhost:999/dev-api/api
{
  "code": 0, 
  "data": "/api", 
  "msg": "success"
}
[root@localhost ~]# curl http://localhost:999/test-api/api
{
  "code": 0, 
  "data": "/test-api/api", 
  "msg": "success"
}
[root@localhost ~]# curl http://localhost:999/api/api
{
  "code": 0, 
  "data": "/api/api", 
  "msg": "success"
}
[root@localhost ~]# 

结论

使用nginx做代理转发时是,是否匹配前缀是否会添加到proxy_passurl后面取决于proxy_pass的url后面是否带/符号。

  • 补充结论

    proxy_passurl 后面携带了/的时候,nginx会将location后面的字符串添加到proxy_pass的url后面。

    现在有两个情景:

    • 配置一

      location /api/ {
        proxy_pass http://x.xx/;
      }
      

      如果请求 /api/getUserInfo,实际转发的请求是http://x.xx/getUserInfo

    • 配置二

      location /api {
        proxy_pass http://x.xx/;
      }
      

      如果请求/api/getUserInfo,实际转发的请求是http://x.xx//getUserInfo

      从上面的结果可以看出nginx直接将location匹配前缀后面的字符串直接拼接到了转发路径后面,不会主动给替换//的情况,目前我知道的是有些web服务会主动给你替换下,但是spring security不会去处理,会认为这是一个不标准的url,可能会有拦截的情况。

问题二:同端口使用不同目录的问题

背景:我们通常使用nginx部署web项目的时候,同一个项目可能有多个静态网站,而这多个静态网站需要使用同一个端口

例如,我的某个web项目有三个服务api服务门户网站管理系统前端,而我想实现利用nginxlocation 匹配前缀不同前缀然后使用8080端口访问,匹配需求如下:

匹配前缀 服务 服务类型
/api 转发到8888端口 接口
/admin 访问/a/b/c目录 静态网页
/ 访问/d/e/f目录 静态网页

想当然使用rootproxy_pass

我对nginx不是非常的熟悉,但是我知道可以使用root来指定静态网页的目录,如果这样的话,我只需要使用location配置块中设置不同root即可,所以有了如下配置:

server {
    listen 8080;
    server_name _;

    location /api {
      proxy_set_header Host $http_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_pass http://127.0.0.1:8888/;
    }

    location /admin {
       root /a/b/c/;
       index index.html;
    } 
   
    location / {
      root /d/e/f/;
      index index.html;
    }
   
}

实测

  • 访问 :8080/api 能正常转发到:8888服务

  • 访问 :8080/admin报502,查看日志发现访问的是 /a/b/c/admin/index.html ,而不是/a/b/c/index.html

  • 访问:8080/正常访问/d/e/f/index.html

结论

本因为是和proxy_pass中的是否以/结尾有关,后来发现修改后测试发现不是, 查阅资料发现需要更改location需要使用到alias

使用alias

server {
    listen 8080;
    server_name _;

    location /api {
      proxy_set_header Host $http_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_pass http://127.0.0.1:8888/;
    }

    location ~ ^/admin(.*)$ {
       alias /a/b/c/$1;
       index index.html;
    } 
   
    location / {
      root /d/e/f/;
      index index.html;
    }
   
}

测试通过!alias可以通过使用正则提取的方式来改变实际访问的路径。

相关文章

网友评论

      本文标题:nginx配置遇到的问题

      本文链接:https://www.haomeiwen.com/subject/onaqiktx.html