问题
upstream 不可 resolve 会阻塞 start/reload
使用 nginx 时, upstream 中若有 server 不可 resolve. start/reload 都会失败.
当把 nginx 作为网关时, 可能有多个服务, 任意服务挂掉. 导致整个网关不可启动. 这明显是不合理的.
only resolve on start/reload
默认情况下, nginx 会在 start/reload 时解析 upstream 里的 server, 并缓存 ips. 因为 docker 容器重启时, ip 会变化, 这会导致缓存的 ip 失效.
解决方案
Use nginx variables
https://serverfault.com/questions/700894/make-nginx-ignore-site-config-when-its-upstream-cannot-be-reached
https://stackoverflow.com/questions/32845674/setup-nginx-not-to-crash-if-host-in-upstream-is-not-found
https://sandro-keil.de/blog/let-nginx-start-if-upstream-host-is-unavailable-or-down/
如:
resolver 127.0.0.11 valid=30s;
location / {
set $target xxx_server_name:3031;
uwsgi_pass $target;
}
优点
可以解决上述两个问题.
缺点
- 不支持多个 server 配置.
- 无法使用 nginx upstream 带来的好处, 如各种负载均衡策略等等.
tengine ngx_http_upstream_dynamic
https://github.com/alibaba/tengine/blob/master/modules/ngx_http_upstream_dynamic_module/ngx_http_upstream_dynamic_module.c
https://tengine.taobao.org/document_cn/http_upstream_dynamic_cn.html
如:
upstream backend {
dynamic_resolve fallback=stale fail_timeout=30s;
server a.com;
server b.com;
}
server {
...
location / {proxy_pass http://backend;}
}
优点
- 大厂, 用的人多.
- 可以解决 only resolve on start/reload 问题.
- 可以和其它 nginx-module 配合.
缺点
- start/reload 时有不可 resolve 的 server 会失败.
jdomain
https://github.com/wdaike/ngx…
upstream backend {
jdomain www.baidu.com port=80;
jdomain www.baidu.com port=81; # 只有一个有效
}
优点
可以解决上述两个问题.
缺点
- 不支持 server 配置, 不支持多个 server, 即 jdomain 的配置, 无法和其它 nginx-module 配合.
- 不支持未 resolved 情况下的启动 (有一个 pr 可以解决这个问题). https://github.com/wdaike/ngx_upstream_jdomain/pull/12
nginx-upstream-dynamic-servers
https://github.com/GUI/nginx-…
优点
- 可以解决上述两个问题.
- 可以和其它 nginx-module 配合.
缺点
- 替换了 nginx server directive, 需要随着 nginx 版本变更维护. 作者测试了的 nginx version: 1.6, 1.7, 1.8, 1.9
- 用的人不够多.
总结
Use nginx variables/jdomain 无法和其它 nginx-upstream-module 很好地配合使用, 不推荐在要求较高的产品中使用.
nginx-upstream-dynamic-servers/tengine ngx_http_upstream_dynamic 可以按实际情况使用.