【问题标题】:Conditionally map values in nginx config有条件地映射 nginx 配置中的值
【发布时间】:2020-04-27 12:14:45
【问题描述】:

我有一个场景,我想 proxy_pass 根据可以出现在标头中或作为查询参数的值向多个上游目的地之一请求。

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

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 块中了) ,我对这种方法持怀疑态度。

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

【问题讨论】:

  • 可以级联两张map,一张map的值作为第二张的默认值。这可能对你有用。
  • 你知道在哪里可以找到文档或示例@RichardSmith 吗?

标签: nginx conditional-statements nginx-config


【解决方案1】:

如果您想先映射$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)。

详情请见this document

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 2019-11-02
    • 2015-06-10
    • 2018-04-22
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多