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

在nginx配置中有条件地映射值,nginx,conditional-statements,nginx-config,Nginx,Conditional Statements,Nginx Config,我有一个场景,我想根据一个可以出现在头中或作为查询参数的值,将代理\u请求传递到几个上游目的地之一 现在,我已经大致了解了基于标题的映射: map $http_x_destination $destination { default upstream0; something upstream1; something2 upstream1; something3 upstream2; } ... server { location / {

我有一个场景,我想根据一个可以出现在头中或作为查询参数的值,将
代理\u请求传递到几个上游目的地之一

现在,我已经大致了解了基于标题的映射:

map $http_x_destination $destination {
    default     upstream0;
    something   upstream1;
    something2  upstream1;
    something3  upstream2;
}
...

server {
    location / {
        proxy_pass https://$destination;
    }
}
显然,这对于存在标头的情况非常有效,但对于目标基于操作的情况则不适用。我最初的直觉是使用某种条件逻辑来查看报头是否存在,如果存在,则基于
$http\u x\u target
,或者
$arg\u target
构建映射

但是我读过很多告诫不要使用
if
,因为这被认为是危险的,而且因为我不知道nginx首先如何处理定义的范围(更不用说在
if
块中),我对这种方法持怀疑态度


有没有一种好方法可以合并这两个信息源,以便将它们的值清晰地映射到上游?

如果您想首先映射
$http\u x\u target
,然后映射
$arg\u target
,有两种解决方案

您可以创建一个复杂的字符串值,如
“$http\u x\u target:$arg\u target”
,并使用正则表达式检查分隔字符的每一侧

例如:

map "$http_x_target:$arg_target" $destination {
    default      upstream0;
    ~something   upstream1;
    ~something2  upstream1;
    ~something3  upstream2;
}
...
server {
    location / {
        proxy_pass https://$destination;
    }
}
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;
    }
}
您可以使用诸如
~^something:
~:something$
之类的正则表达式来测试字符串中
的每一侧


或者使用第一个贴图的值作为第二个贴图的默认值来级联两个贴图

例如:

map "$http_x_target:$arg_target" $destination {
    default      upstream0;
    ~something   upstream1;
    ~something2  upstream1;
    ~something3  upstream2;
}
...
server {
    location / {
        proxy_pass https://$destination;
    }
}
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\u destination


有关详细信息,请参阅。

您可以级联两个贴图,以便将一个贴图的值用作第二个贴图的默认值。这可能对你有用。你知道@RichardSmith在哪里可以找到文档或例子吗?