有条件地映射 nginx 配置中的值 [英] Conditionally map values in nginx config
问题描述
我有一个场景,我想根据可以出现在标头中或作为查询参数的值将请求 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屋!