Nginx 动态 proxy_pass 无法正确解析

Nginx 动态 proxy_pass 无法正确解析

我在配置 nginx 时遇到了问题,我在网上搜索了解决方案,并且得到了一些零碎的信息,但我仍然无法找到正确的配置。

我已经注册了一个域名,比如说 - www.example.com。我已经在注册商网站上配置了所有内容,ping www.example.com 和 www.*.example.com 成功。

我的机器上运行着 Apache Tomcat,监听端口 8080。我想设置动态 proxy_pass。因此,如果我的应用程序 MyApp 在 tomcat 中运行,并且可以通过 localhost:8080/MyApp 访问,我希望能够通过 www.MyApp.example.com 访问它,因此子域名基本上就是 tomcat 中应用程序的名称。

这是我的 nginx 配置:

server {
  server_name ~^(www\.)?(?<sub_domain>.+)\.example\.com$;
  listen 80;

  location / {
     proxy_pass http://localhost:8080/$sub_domain/;
  }
}

当我访问 www.myapp.example.com 时,我被重定向到http://localhost:8080/myapp- 我的意思是我最终进入了http://localhost:8080/myapp我的浏览器。

但是,如果我将 nginx 设置中的正则表达式更改为:

server {
      server_name www.myapp.example.com myapp.example.com
      listen 80;

      location / {
         proxy_pass http://localhost:8080/myapp/;
      }
    }

然后一切都很顺利。我知道这和解析器有关,我已经尝试将解析器放入 nginx 中,但没有任何变化。

我在这里遗漏了什么?

//编辑:

这是我的配置。我仍然被重定向到 www.myapp.example.com/myapp/login,而不是 www.myapp.example.com/login。我更改了正则表达式,结果还是一样。

  http {

    upstream backend {

             server 127.0.0.1:8080;

    }

    server {                                                         
          server_name ~^(www\.)?(?<sub_domain>.+)\.example\.com$;
          listen 80;                                                        


           location / {
               proxy_set_header "Host" $host;
               proxy_pass http://backend/prefix-$sub_domain/;

               proxy_redirect http://$host/prefix-$sub_domain/ http://$host;

           }

    }

卷曲:

* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET /prefix-myapp/ HTTP/1.1
> User-Agent: curl/7.35.0
> Accept: */*
> Host: www.myapp.example.com
>
< HTTP/1.1 302 Found
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Set-Cookie: JSESSIONID=E609EB96D8F27FD6F4E7F9ED9ACA5245; Path=/prefix-myapp/; HttpOnly
< Location: http://www.myapp.example.com/prefix-myapp/login;jsessionid=E609EB96D8F27FD6F4E7F9ED9ACA5245
< Content-Length: 0
< Date: Tue, 21 Oct 2014 16:48:05 GMT
<
* Connection #0 to host 127.0.0.1 left intact

编辑://

非常感谢 Xavier!添加以下两行很有帮助:

proxy_pass http://backend/prefix-$domain$request_uri;
proxy_redirect http://$host/prefix-$domain http://$host;

还有2个问题:

  1. 这个配置对性能影响大吗?
  2. 我可以从 $request_uri 中过滤掉一些东西吗 (例如 JSESSIONID=1233....)?

再次感谢!我花了一个星期才弄清楚!

答案1

当你在指令中使用变量时proxy_pass,nginx 将使用运行时解析,除非:

  • 目标服务器被声明为 IP 地址
  • 目标服务器名称是上游服务器组的一部分
  • 目标服务器名称已被解析(例如,它与另一个服务器块中的服务器名称匹配)

在这里,运行时解析器不会有帮助,因为 localhost 可能无法通过 DNS 解析。此外,运行时解析是一种浪费,因为在这里您显然可以避免它。

因此,有两个简单的解决方案:

  • 使用127.0.0.1
  • 声明上游块如果您有服务器名称或目标服务器池

现在您需要确保代理服务器重定向正确。因此,请执行以下操作之一:

  • 您的代理目标处理主机头并通过以下方式传递它:

    proxy_set_header "Host" $host;

  • 您的代理目标无法处理重定向的 Host 标头,您需要使用 nginx 重写它们:

    proxy_redirect http://$proxy_host/$sub_domain http://$host;

但是如果它根本不支持 Host 标头,链接就会断开。

相关内容