有条件地映射 nginx 配置中的值 [英] Conditionally map values in nginx config

查看:54
本文介绍了有条件地映射 nginx 配置中的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a scenario where I want to proxy_pass requests to one of several upstream destinations based on a value which can appear in a header or as a query parameter.

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

Right now, I've got the header-based mapping mostly figured out:

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

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

显然,这适用于我们有标题的情况,但不适用于目标基于操作的情况.我最初的直觉是使用某种条件逻辑来查看标题是否存在,如果存在,则基于 $http_x_target$arg_target 构建地图.

Obviously this works well for the cases where we have a header present, but not for those cases where the target is based on an operation. My initial instinct would be to use some sort of conditional logic to see if the header is present, and construct the map based on $http_x_target if it is, or $arg_target instead.

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

But I've read plenty of exhortations not to use if, as it's considered dangerous, and since I don't know how nginx handles the scoping of definitions in the first place (let alone in if blocks), I'm leery of this approach.

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

Is there a good way to merge these two sources of information in order to cleanly map their values to upstreams?

推荐答案

如果你想先映射 $http_x_target 再映射 $arg_target,有几个解决方案.

If you want to map $http_x_target first and $arg_target second, there are a couple of solutions.

您可以创建一个复杂的字符串值,如 "$http_x_target:$arg_target" 并使用正则表达式检查分隔字符的每一侧.

You could create a complex string value like "$http_x_target:$arg_target" and use regular expressions to check each side of the separating character.

例如:

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

您可以使用诸如 ~^something:~:something$ 之类的正则表达式来测试字符串中 : 的每一侧.

You could use regular expressions like ~^something: and ~:something$ to test each side of the : in the string.

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

Or cascade two maps by using the value of the first as the default of the second.

例如:

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).

The two maps must control different variable names (e.g. $destination and $arg_destination).

有关详细信息,请参阅本文档.

See this document for details.

这篇关于有条件地映射 nginx 配置中的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆