关于 nginx 中 proxy_pass 指令我有些疑惑

278 天前
 21231sv
upstream example {
    server 172.0.0.1:3000;
    server 172.0.0.2:3000;
}

server {
    listen 3000;
    server_name _;
    location / {
        proxy_pass http://example;
        proxy_ssl_verify off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-Ip $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

对于上面这个配置,我理解的是,假如客户端请求的是 http://ip:3000/path?a=1&b=2, nginx 会根据 example 这个 upstream 选择一个后端服务器转发请求,比如 http://172.0.0.1:3000/path?a=1&b=2

但是我在工作中有碰到过如下配置:

  location ~ ^/api/(.*) {
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-Ip $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_pass http://172.0.0.3:31081/$1$is_args$args;
      proxy_connect_timeout 300s;
      proxy_send_timeout 300s;
      proxy_read_timeout 300s;
  }

在这个配置中,proxy_pass 指令后面有 $is_args 、$args 这些参数。如果不加参数,客户端请求 url 上的参数就无法转发到 172.0.0.3 服务器上

我想要的是要把客户端请求 url 中的参数转发到后端,我的疑惑是什么时候 proxy_pass 指令后面需要加 $is_args 、$args 这些参数

1051 次点击
所在节点    问与答
11 条回复
hankai17
278 天前
可能跟 upstream 模块有关
GTim
278 天前
看 172.0.0.3:31081 这台的 nginx 日志
privil
278 天前
(.*) 这个参数在上下文里面不匹配 url 上的参数吧,话说用了那么多年 Nginx ,我也是第一次见第二种写法。直接去掉正则也可以吧。
location ~ ^/api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://172.0.0.3:31081/;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
crystom
278 天前
很可能跟末尾有没有斜杠有关系
dzdh
278 天前
proxy_pass 到 127.0.0.1:xx 然后看日志
xiangyuecn
278 天前
按道理,第二种才是正常写法。

第一种写多了,只会误导人,来个高级一点的就不会写了。
wu00
278 天前
@privil 应该做了一层 path strip 吧? /api/xxx => /xxx , 你这个/api/前缀带到服务层就 404 了
privil
278 天前
@wu00 #7 你可以试试我这种写法会不会带过去。我看漏了中间一堆他自己的理解,啥理解,多个 upsteam 是有个默认算法的请求的。脑补严重。
jifengg
278 天前
以我有限的 nginx 经验,楼主的第二个配置
location ~ ^/api/(.*) {
proxy_pass http://172.0.0.3:31081/$1$is_args$args;
}
的目的,是把类似 http://host/api/your/path?key=value 转发到 http://172.0.0.3:31081/your/path?key=value

是把“/api”这层 path 换成“/”,应该是 172.0.0.3:31081 的 api (?)服务不需要加 “/api”前缀。

$1 就是 location 正则里面的 第一个 group ,$is_args 是表示是否有 searchPath ,值是"?"或空,$args 则表示 key=value&a=b 这整个 get 参数。

有个简化的版本可以参考(也是达到“转发时去掉 url 中的/api 的目的”):
location /api {
proxy_pass http://172.0.0.3:31081/; #注意这里最后的/不能省
}
21231sv
277 天前
@xiangyuecn #6 为什么这么说?我看官网上都是第一种写法
21231sv
277 天前
@jifengg #9 这么说,我上次应该就是省略了 31081 后面的 /

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/963576

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX