我们在Docker的公共域下有几个rails应用程序,我们使用nginx将请求定向到特定的应用程序。
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
配置如下:
upstream foo {
server foo:3000;
}
upstream bar {
server bar:3000;
}
# and about 10 more...
server {
listen *:80 default_server;
server_name our_dev_server.com;
location /foo {
# this is specific to asset management in rails dev
rewrite ^/foo/assets(/.*)$ /assets/$1 break;
rewrite ^/foo(/.*)$ /foo/$1 break;
proxy_pass http://foo;
}
location /bar {
rewrite ^/bar/assets(/.*)$ /assets/$1 break;
rewrite ^/bar(/.*)$ /bar/$1 break;
proxy_pass http://bar;
}
# and about 10 more...
}
如果其中一个应用程序未启动,则nginx将失败并停止:
host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
我们不需要它们全部启动,但nginx在其他方面会失败。如何使nginx忽略失败的上游?
>
如果您可以使用静态IP,那么只需使用它,它将启动并在没有响应时返回503
。
使用resolver
指令指向可以解析主机的内容,无论主机当前是否处于运行状态。
如果无法执行上述操作,请在位置
级别解决此问题(这将允许Nginx启动/运行):
location /foo {
resolver 127.0.0.1 valid=30s;
# or some other DNS (your company's internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.1 valid=30s;
# or some other DNS (your company's internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
对我来说,来自@Justin/@duskwuff的答案选项3解决了这个问题,但是我必须将解析器IP更改为127.0.0.11(Docker的DNS服务器):
location /foo {
resolver 127.0.0.11 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.11 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
但正如@Justin/@dashwuff所提到的,您可以使用任何其他外部DNS服务器。
使用上游
的主要优点是定义一组服务器,这些服务器可以侦听不同的端口,并在它们之间配置负载平衡和故障切换。
在您的情况下,每个上游只定义一个主服务器,因此它必须启动。
相反,为您的proxy_pass
(es)使用变量,并记住处理目标服务器关闭时可能出现的错误(404s,503s)。