• Nginx——proxy_pass url 反向代理


    说到 Nginx 就不得不说 Nginx 的反向代理是多么的好用,一个指令 proxy_pass 搞定反向代理,对于接口代理、负载均衡很是实用,但 proxy_pass 指令后面的参数很有讲究。

    在实际的应用中分为以下几种情况:

    1.url 只是 host

    这里指不包含 $uri ,如:

    • http://host - √
    • https://host - √
    • http://host:port - √
    • https://host:port - √
    • http://host/ - x
    • http://host:port/ - x

    这时候 location 匹配的完整路径将直接透传给 url ,如:

    // 访问:   /                               后端:   /
    // 访问:   /api/xx                         后端:   /api/xx
    // 访问:   /api/xx?aa                      后端:   /api/xx?aa
    location / {
        proxy_pass http://node:8080;
    }
    
    // 访问:   /api/                           后端:   /api/
    // 访问:   /api/xx                         后端:   /api/xx
    // 访问:   /api/xx?aa                      后端:   /api/xx?aa
    // 访问:   /api-xx?aa                      后端:
    location /api/ {
        proxy_pass http://node:8080;
    }
    
    // 访问:   /api/                           后端:   /api/
    // 访问:   /api/xx                         后端:   /api/xx
    // 访问:   /api/xx?aa                      后端:   /api/xx?aa
    // 访问:   /api-xx?aa                      后端:   /api-xx?aa
    location /api {
        proxy_pass http://node:8080;
    }

    2.url 包含路径

    注意,这里的路径哪怕只是一个 / 也是存在的,如:

    • http://host - x
    • https//host/ - √
    • http://host:port - x
    • https://host:port/ - √
    • http://host/api - √
    • http://host/api/ - √

    当 proxy_pass url 的 url 包含路径时,匹配时会根据 location 的匹配后的链接透传给 url ,注意匹配后就是这样:

    location 规则访问的原始链接匹配之后的路径
    location / /  
    location / /a a
    location / /a/b/c?d a/b/c?d
    location /a/ /a/  
    location /a/ /a/b/c?d b/c?d

    明白匹配之后的路径后,在 proxy_pass url 包含路径时,将会把匹配之后的路径透传给 url ,如:

    // 访问:   /                               后端:   /
    // 访问:   /api/xx                         后端:   /api/xx
    // 访问:   /api/xx?aa                      后端:   /api/xx?aa
    location / {
        proxy_pass http://node:8080/;
    }
    
    // 访问:   /api/                           后端:   /
    // 访问:   /api/xx                         后端:   /xx
    // 访问:   /api/xx?aa                      后端:   /xx?aa
    // 访问:   /api-xx?aa                      未匹配
    location /api/ {
        proxy_pass http://node:8080/;
    }
    
    // 访问:   /api                            后端:   /
    // 访问:   /api/                           后端:   //
    // 访问:   /api/xx                         后端:   //xx
    // 访问:   /api/xx?aa                      后端:   //xx?aa
    // 访问:   /api-xx?aa                      后端:   /-xx?aa
    location /api {
        proxy_pass http://node:8080/;
    }
    
    // 访问:   /api/                           后端:   /v1
    // 访问:   /api/xx                         后端:   /v1xx
    // 访问:   /api/xx?aa                      后端:   /v1xx
    // 访问:   /api-xx?aa                      未匹配
    location /api/ {
        proxy_pass http://node:8080/v1;
    }
    
    // 访问:   /api/                           后端:   /v1/
    // 访问:   /api/xx                         后端:   /v1/xx
    // 访问:   /api/xx?aa                      后端:   /v1/xx
    // 访问:   /api-xx?aa                      未匹配
    location /api/ {
        proxy_pass http://node:8080/v1/;
    }

    3.当 proxy_pass 遇到正则

    当 location 以正则形式匹配时,proxy_pass 就不能以 / 结束了,也就是不能包含路径了,比如错误的:

    location ~* ^/api/ {
        proxy_pass http://host/;
    }
    
    location / {
        if ($uri ~* ^/api/) {
            proxy_pass http://host/;
        }
    }

    解决办法就是把链接中的路径去掉。

    4.重写代理链接 - url rewrite

     当原始链接(浏览器访问的链接)和代理服务器链接规则不一致时,可以使用 Nginx URL Rewrite 功能去动态的重写,如:

    location ~* ^/api/ {
        rewrite ^/api/(.*) /?path=$1 break;
        proxy_pass http://node:8080;
    }

    以上请求会把匹配 /api/ 的链接重写为 /?path= 的链接透传给 node:8080 服务,有意思的是当使用 rewrite 指令并且生效后,proxy_pass url 链接中的路径会被忽略,如:

    // 访问:   /                               后端:   /node/
    // 访问:   /api                            后端:   /node/api
    // 访问:   /api/                           后端:   /?path=
    // 访问:   /api/a/b/c                      后端:   /?path=a/b/c
    location / {
        rewrite ^/api/(.*) /?path=$1 break;
        proxy_pass http://node:8080/node/;
    }

    参考:https://xuexb.github.io/learn-nginx/example/proxy_pass.html

  • 相关阅读:
    C++primer拾遗(第五章:语句)
    每日编程-20170315
    C++primer拾遗(第四章:表达式)
    C++primer拾遗(第三章:字符串、向量和数组)
    每日编程-20170314
    C++primer拾遗(第二章:变量和基本类型)
    每日编程-20170313
    每日编程-20170310
    每日编程-20170309
    C++primer拾遗(第一章:开始)
  • 原文地址:https://www.cnblogs.com/caoweixiong/p/12213993.html
Copyright © 2020-2023  润新知