在 Nginx 反向代理中使用动态主机时替换 URI

Ham*_*amy 5 nginx reverse-proxy dynamic

仅供参考 - 我怀疑这有一个非常明显/简单的答案(我是 nginx 的新手)

我使用动态上游作为我的 Nginx 配置的一部分。这意味着在proxy_pass指令中使用变量,resolver如果上游有问题(未知主机/不可连接),它会指示 nginx 使用而不是崩溃/不启动。

但是,这似乎也改变proxy_pass了对 URI 的处理。它不是用proxy_pass指令中指定的 URI 替换请求 URI ,而是忽略请求 URI。我正在寻找一种方法来保留(或重现)允许我继续使用动态主机的原始行为。

我试图在这里创建一个最小的示例配置:

server {
    listen 80;
    server_name my-server.com;

    # My chosen DNS server (in this case, the Docker DNS)
    resolver 127.0.0.11 valid=30s ipv6=off;

    # This works
    location / {
        set $upstream frontend:8080;
        proxy_pass http://$upstream;
    }

    # This does not work :-( 
    # The original URI (e.g. /api/users/tommy) is ignored, and 
    # all requests to api-server are directly to /api/
    location /api/ {
        set $upstream api-server:8002;
        proxy_pass http://$upstream/api/;
    }
}
Run Code Online (Sandbox Code Playgroud)

一种解决方法是从proxy_pass指令中删除 URI,并让上游服务器侦听所需的确切 URI。这并不理想,因为网关服务器的核心优势是增加了一些独立更改的灵活性(如果需要,重写 URI)

例如,

    # This kind of works, but upstream must listen on /api 
    location /api {
        set $upstream api-server:8002;
        proxy_pass http://$upstream;
    }
Run Code Online (Sandbox Code Playgroud)

Ric*_*ith 6

文件指出,如果你在使用变量proxy_pass指令,并指定一个URI部分,将通过上游“原样”。

您需要捕获需要向上游发送的 URI 部分。要么使用正则表达式location块,例如:

location ~ ^/api(.*)$ {
    set $upstream ...;
    proxy_pass http://$upstream$1;
}
Run Code Online (Sandbox Code Playgroud)

或者使用 arewrite...break来改变当前的 URI,例如:

location /api {
    set $upstream ...;
    rewrite ^/api(.*)$ $1 break;
    proxy_pass http://$upstream;
}
Run Code Online (Sandbox Code Playgroud)