在nginx配置中有条件地映射值

3
我有一个场景,希望能够根据出现在头部或查询参数中的值,将请求代理到多个上游目标之一。目前,我已经基本解决了基于头部的映射:
map $http_x_destination $destination {
    default     upstream0;
    something   upstream1;
    something2  upstream1;
    something3  upstream2;
}
...

server {
    location / {
        proxy_pass https://$destination;
    }
}

显然,这对于存在标题的情况非常有效,但对于基于操作的目标则无效。我的最初想法是使用某种条件逻辑来查看标题是否存在,并根据 $http_x_target 构建映射表,如果不存在,则使用 $arg_target。但我已经读过很多不要使用if的警告,因为它被认为是危险的,而且由于我不知道nginx首先如何处理定义的作用域(更不用说在if块中了),所以我对这种方法持谨慎态度。有没有一种好的方法将这两个信息源合并,以便将它们的值干净地映射到上游?

你可以级联两个映射,使得第一个映射的值被用作第二个映射的默认值。这可能对你有用。 - Richard Smith
你知道在哪里可以找到这个文档或示例吗,RichardSmith? - a p
1个回答

2
如果你想先映射$http_x_target,然后是$arg_target,有几种解决方案。
你可以创建一个复杂的字符串值,比如"$http_x_target:$arg_target",并使用正则表达式来检查分隔符两侧。
例如:
map "$http_x_target:$arg_target" $destination {
    default      upstream0;
    ~something   upstream1;
    ~something2  upstream1;
    ~something3  upstream2;
}
...
server {
    location / {
        proxy_pass https://$destination;
    }
}

您可以使用正则表达式,例如~^something:~:something$来测试字符串中:两侧的内容。


或者通过使用第一个映射的值作为第二个映射的默认值来级联两个映射。

例如:

map $arg_target $arg_destination {
    default     upstream0;
    something   upstream1;
    something2  upstream1;
    something3  upstream2;
}
map $http_x_target $destination {
    default     $arg_destination;
    something   upstream1;
    something2  upstream1;
    something3  upstream2;
}
...
server {
    location / {
        proxy_pass https://$destination;
    }
}

两个映射必须控制不同的变量名(例如$destination$arg_destination)。
有关详细信息,请参见此文档

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接