nginx 负载平衡问题,后端有 301

nginx 负载平衡问题,后端有 301

我遇到了一个奇怪的问题,我不确定这是配置问题还是 nginx 中的错误。我的设置是一个 nginx 反向代理,它有 Apache2 后端服务器。负载平衡器非常基础,类似于来自 wiki 的示例,例如简化:

http {
  upstream myproject {
    server 127.0.0.1:8000;
  }

  server {
    listen 80;
    location / {
      proxy_pass http://myproject;
    }
  }
}

现在,当我尝试在 Apache 中请求目录时,如果 URL 末尾没有斜杠,就会出现问题。例如,客户端请求:

http://apache.myserver.com/somedirectory

Apache 将回复 HTTP 302,以将客户端重定向到

http://apache.myserver.com/somedirectory/

请注意,url 末尾有一个斜杠,表示它是一个目录。还请注意,Apache 很“聪明”,在重定向标头中使用传入请求的主机名。到目前为止一切正常。但是,当使用具有负载平衡的 nginx 时,此 301 会发送到客户端,而不会将 nginx 上游名称转换回实际的服务器/域。因此,客户端将收到以下内容:

GET http://nginx.myserver.com/somedirectory
HTTP 301 Moved Permanently
...
Location: http://myproject:8000/somedirectory/

myproject是 nginx 上游后端的名称。它不是客户端可以解析的实际主机。在我看来,客户端应该被重定向到

http://nginx.myserver.com/somedirectory/  

即,上游后端的名称应该在响应标头中被替换。这是 nginx 中的错误还是我做错了什么?

答案1

事实证明,nginx 有很多代理重定向处理此类问题的选项。我最终使用了类似这样的方法:

location / {
    proxy_pass  http://myproject;
    proxy_set_header Host myproject;
    proxy_redirect http://myproject/ $scheme://$host/;
    proxy_redirect http://myproject:8000/ $scheme://$host/;
}

这基本上用 $host 替换上游名称并删除端口。这在我的情况下有效,因为我在 HTTP/HTTPS 的默认端口上托管 nginx。如果 nginx 在非默认端口上运行,则需要类似以下内容:

    proxy_redirect http://myproject/ $scheme://$host:$server_port/;
    proxy_redirect http://myproject:8000/ $scheme://$host:$server_port/;

答案2

尝试使用重定向的服务器名称像这样:

server_name_in_redirect off;

如果这不起作用,你可能需要做点什么代理重定向,尽管听起来你的后端运行正常。

相关内容