我主要将 nginx 用作几个 gunicon/mod_wsgi 应用程序前面的反向缓存代理,当然也用于服务器静态文件。
我发现我的 nginx 配置很快就变得无法维护;问题是我有几个相似(甚至相同)的模式,但我无法设法使其清理干净。
我遇到的最大问题之一是,我很想使用命名位置来对一组会议进行分组,例如。
location @django_modwsgi {
include proxy.conf;
proxy_pass http://127.0.0.1:8080;
}
location @django_gunicorn {
include proxy.conf; # this could also be included directly in the server {} block?
proxy_pass http://gunicorn_builder;
}
注意: 问题是不是同时拥有 gunicorn 和 wsgi。这只是一个例子。另一个是:
location @namedlocation_1 {
some cache settings;
some cache_key settings;
ignore some headers;
expires;
proxy_pass
}
location @namedlocation_2 {
other cache settings;
other cache_key settings;
ignore some headers;
expires;
proxy_pass
}
但要调用命名位置,我发现的唯一方法是:
location /somelocation {
try_files $uri @named_location;
}
这已经感觉不对了,我确实不是想要 nginx 去查找静态文件,我希望它直接去命名位置!有没有办法直接“调用”命名位置?!
我认为可以采用干燥的另一种方法是大量include
......
location /somelocation {
include django_unicorn.conf;
}
但这是好办法吗?对于非常通用的设置(例如代理设置),这听起来还不错,但必须打开不同的文件才能获得完整的配置,这样可读性就很差了。
此外,在某些情况下,我可以使用正则表达式对几个位置进行分组,但我只喜欢在它们在逻辑上相关时这样做,而不仅仅是能够将通用设置放在同一个块中。
问题
是否存在“官方”最佳实践来编写好的、DRY nginx 配置?
我很想找到这样的模式:
location / {
common confs
try_files $uri @name_location
}
** 但是我该如何针对不同的地点编写具体案例?**
我可以简单地使用 conf 中不常见的部分和 @named_location 中的常见部分添加几个位置吗?
location /1/ {
some cache expire settings;
NOTHING ELSE;
}
location /2/ {
some other cache expire settings;
NOTHING ELSE;
}
location / {
common settings
try_files
}
location @named_location {
other common settings for this named location only
proxy_pass
}
当我有指向同一资源的不同 URL 时,我可以简单地重写吗?
location /1/ {
rewrite ^ /3/ last;
}
location /2/ {
rewrite ^ /4/ last;
}
location / {
common settings
try_files
}
location @named_location {
other common settings for this named location only
proxy_pass
}
或者应该把它们全部分组到一个位置?
location / {
rewrite ^/1/$ /3/ last;
rewrite ^/2/$ /4/ last;
common settings
try_files
}
location @named_location {
other common settings for this named location only
proxy_pass
}
有关的
我在邮件列表中找不到太多信息,在 wiki 中就更少了。
请注意,这与问题不同NGinx 最佳实践- 这是一个非常笼统的问题。
另一个更相关:我该如何使这个 Nginx 配置 DRY 起来?
答案1
我已经使用 nginx map 功能解决了类似的问题。
首先创建域名到后端的映射:
map $http_host $backend {
myhost1.tld 192.168.1.100;
myhost2.tld 192.168.1.101;
default upstream_pool1;
}
然后使用位置中的地图
location / {
common settings
proxy_pass $backend;
}
您可以使用任何其他变量代替 $http_host 请参阅本手册:http://nginx.org/en/docs/http/ngx_http_map_module.html
答案2
有没有办法直接“调用”命名位置?!
至少还有一种方法:
location /somelocation {
error_page 418 = @named_location;
return 418;
}
答案3
一些指令可以同时应用于“服务器”和“位置”上下文,从而使其变得 DRY:
# The variables below are evaluated on each request,
# allowing to DRY configs of locations.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr;
location /special {
proxy_send_timeout 10m;
proxy_read_timeout 10m;
proxy_pass http://pool;
}
location / {
proxy_pass http://pool;
}
答案4
有没有办法直接“调用”命名位置?!==> 这很简单
尝试文件/dev/null@test;