如何在 Nginx 配置的上游块中公开服务器端口?

how to expose server port in upstream block of Nginx configuration?

SOA 模式下,我们有一些松散的同质应用程序。由于同质性,我们已经能够在 Nginx 中定义一些简洁的模式来通过一个配置代理我们所有的 SOA 应用程序。遵循 Nginx 配置与 DNSmasq 一起解决 anything.yourdomain.devel 绝对是绝对奇迹。 a.Whosebug.develb.Whosebug.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 负载均衡器后面模拟多台服务器。我想做以下指向上游而不是直接指向一对 server:port 的代理配置。

proxy_pass http://backend;

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

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

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

Is this an expected behavior?

是的,上游内部不能使用变量。您可以创建几个具有不同名称(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: proxy_pass backend_$app; 中使用 $app 跳过 map 块,但需要对 $app 值进行额外检查。此外,map 允许将不同的 "domains" 映射到相同的应用程序。