【问题标题】:how to expose server port in upstream block of Nginx configuration?如何在 Nginx 配置的上游块中公开服务器端口?
【发布时间】:2017-01-10 22:49:49
【问题描述】:

SOA 模式下,我们有一些松散的同质应用程序。由于同质性,我们已经能够在 Nginx 中定义一些简洁的模式来通过一个配置代理我们所有的SOA 应用程序。遵循 Nginx 配置绝对可以与DNSmasq 一起解决anything.yourdomain.devel 问题,例如。 a.stackoverflow.develb.stackoverflow.devel 域并通过地图通过指定端口将其路由到项目文件夹下的适当应用服务器。

 worker_processes  2;

    events {
      worker_connections  1024;
    }

    http {

          map $host $static_content_root {
            hostnames;
            default /path/to/project/folder;
            # For typical standalone apps living in your project directory
            # *.myapp.local.devel -> /path/to/project/myapp/public
            ~^([^\.]+\.)*(?<app>[^\.]+)\.devel$ /path/to/project/folder/$app/public; #rails pattern
          }

          map $app $devel_proxy_port1 {
            default 3000;
            domain1 3000;         
            domain2 4000;

          }

          map $app $devel_proxy_port2 {
            default 3001;
            domain1 3001;
            domain2 4001;
          }

          server {
            listen 127.0.0.1;
            server_name  ~^([^\.]+\.)*(?<app>[^\.]+)\.[^\.]+.devel$;


            location / {
              root  $static_content_root; # Using the map we defined earlier
              try_files $uri $uri/index.html @dynamic;
            }

            location @dynamic {
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forward-Proto http;
                proxy_set_header X-Nginx-Proxy true;
                proxy_redirect off;
                proxy_pass http://127.0.0.1:$devel_proxy_port1;
            }
          }
        }

现在,为了在 Nginx 负载均衡器后面模拟多台服务器。我想过做以下代理配置,它指向上游而不是直接指向一个服务器:端口对。

proxy_pass http://backend;

upstream backend {
   server http://127.0.0.1:$devel_proxy_port1;
   server http://127.0.0.1:$devel_proxy_port2;
}

我认为上述方法可行,但它总是发出以下错误提示 ma​​p 块的变量在 upstream 上下文中不可用。

[emerg] 69478#0: invalid host in upstream "http://127.0.0.1:$devel_proxy_port1" in /usr/local/etc/nginx/nginx.conf:57

这是预期的行为吗?

【问题讨论】:

    标签: nginx reverse-proxy


    【解决方案1】:

    是的,变量不能在上游使用。您可以创建几个不同名称的上游块(upstream backendupstream backend_domain 等),通过map 解析上游名称并将此变量放入proxy_pass

    upstream backend {
     server http://127.0.0.1:3000;
     server http://127.0.0.1:3001;
    }
    
    upstream backend_domain1 {
     server http://127.0.0.1:3002;
     server http://127.0.0.1:3003;
    }
    
    upstream backend_domain2 {
     server http://127.0.0.1:3004;
     server http://127.0.0.1:3005;
    }
    
    ...
    
    upstream backend_domain30 {
     server http://127.0.0.1:3060;
     server http://127.0.0.1:3061;
    }
    
    map $app $devel_proxy {
     default backend;
     domain1 backend_domain1;
     domain2 backend_domain2;
     ...
     domain30 backend_domain30;
    }
    
    ...
    proxy_pass $devel_proxy;
    ...
    

    在某些情况下,您可以在proxy_pass 内使用$app 跳过map 块:proxy_pass backend_$app;,但需要对$app 值进行额外检查。此外,map 允许将不同的“域”映射到相同的应用程序。

    【讨论】:

    • 我查询的重点是获取上游块内的参数化端口。每个应用程序都分配有一对端口,端口取自映射,具体取决于域的名称标识符,例如。 dmitry.stackoverflow.com 在 stackoverflow.com 域上具有名称 dmitry,并且在 stackoverflow 上有许多名称映射到一对端口。您的答案是否足以满足这种情况?我不明白怎么做?
    • 您需要为每个名称标识符创建单独的upstream
    • 我知道如果你有一个应用程序绑定到 3000 和 3001 端口但在上游,端口需要一个变量,以便它可以根据 $app 上的映射块动态分配端口。根据第一篇文章的第一个地图块,$app 可能有 30 个不同的值。为简洁起见,我只展示了 $app 的两个可能值,即。域1 和域2
    • 30 个不同的 $app... 每个 $app 都有单独的端口(甚至两个),对吧?域 1 - 3000、3001;域2 - 3002、3003; ... domain30 - 3058, 3059?所以你需要创建 30 个upstream 块。编辑答案。
    • 分离上游更灵活。例如,仅将第 3 个应用程序实例轻松添加到 domain25。此外,如果您对几个域使用相同的应用程序实例 - 只需 map 这个域到相同的上游。
    猜你喜欢
    • 1970-01-01
    • 2011-08-13
    • 2020-02-04
    • 2017-03-16
    • 2018-09-11
    • 2017-12-27
    • 2018-12-31
    • 2021-05-10
    • 2018-03-06
    相关资源
    最近更新 更多