Nginx proxy_pass 只能部分工作

Nginx proxy_pass only works partially

我有以下设置

两个 运行 Nginx 在 Ubuntu 16.04

在主服务器上,我在 /etc/nginx/sites-available/default 文件中创建了以下配置块

location /test
{
 rewrite ^/test(.*) / break;
 proxy_pass https://slave.com;
 proxy_read_timeout 240;
 proxy_redirect off;
 proxy_buffering off;
 proxy_set_header Host $host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto https;
}

A service nginx reload 稍后 master.com 我可以执行以下操作

但是,我无法执行以下任何操作

这显然是因为我在 master.com 上的 Nginx 配置中遗漏了一些东西。但是,我看不出那可能是什么。

为了完整起见,这是我在两台服务器上的配置:

Ubuntu - 16.04.3 Nginx - 1.10.3 PHP - 7.0.22

我应该解释为什么 ^~ 是必需的,因为这在我最初的问题中并不清楚。我有另一个块设置来处理 master.com.

上的 PHP 脚本
location ~ \.php$ 
{
 try_files $uri =404;
 fastcgi_split_path_info ^(.+\.php)(/.+)$;
 fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 include fastcgi_params;
}

由于 Nginx 处理这些指令的方式,此块在处理 .php 文件时优先,并且 master.com 最终在本地查找 .php 实际上位于 slave.com。避免这种情况的唯一方法是使用 ^~

你的做法是错误的。在处理 /test 的块内重写它并将其发送出块。 proxy_pass 实际上从未发生过,因为新的 URL 中没有 /test。解决方法很简单,不要用rewrite

location /test/
{
 proxy_pass https://slave.com/;
 proxy_read_timeout 240;
 proxy_redirect off;
 proxy_buffering off;
 proxy_set_header Host $host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto https;
}

在位置路径的末尾附加 / 以及 proxy_pass 服务器将确保将 /test/ 之后的内容发送到您的 proxy_pass 地址

编辑-1

这是我在发布此答案之前设置的示例测试用例。

events {
    worker_connections  1024;
}
http {
server {
   listen 80;

   location /test1 {
     proxy_pass http://127.0.0.1:81;
   }

   location /test2 {
     proxy_pass http://127.0.0.1:81/;
   }

   location /test3/ {
     proxy_pass http://127.0.0.1:81;
   }

   location /test4/ {
     proxy_pass http://127.0.0.1:81/;
   }

}

server {
   listen 81;

   location / {
     echo "$request_uri";
   }
}
}

现在结果解释了所有 4 个位置块之间的差异

$ curl http://192.168.33.100/test1/abc/test
/test1/abc/test

$ curl http://192.168.33.100/test2/abc/test
//abc/test

$ curl http://192.168.33.100/test3/abc/test
/test3/abc/test

$ curl http://192.168.33.100/test4/abc/test
/abc/test

正如您在 /test4 url 中看到的那样,代理服务器只能看到 /abc/test