使用nginx時, upstream中如有server不可resolve. start/reload都會失敗.
當把nginx做爲網關時, 可能有多個服務, 任意服務掛掉. 致使整個網關不可啓動. 這明顯是不合理的.html
默認狀況下, nginx會在start/reload時解析upstream裏的server, 並緩存ips. 由於docker容器重啓時, ip會變化, 這會致使緩存的ip失效.nginx
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/
如:git
resolver 127.0.0.11 valid=30s; location / { set $target xxx_server_name:3031; uwsgi_pass $target; }
能夠解決上述兩個問題.github
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
如:docker
upstream backend { dynamic_resolve fallback=stale fail_timeout=30s; server a.com; server b.com; } server { ... location / { proxy_pass http://backend; } }
https://github.com/wdaike/ngx...緩存
upstream backend { jdomain www.baidu.com port=80; jdomain www.baidu.com port=81; # 只有一個有效 }
能夠解決上述兩個問題.負載均衡
https://github.com/GUI/nginx-...dom
咱們使用的是tengine-2.2.2, 看代碼能夠知道. 替換tengine server directive會致使id/host 沒有設置到ngx_http_upstream_server_t結構體中. 由於id/host在咱們的使用場景中都沒有用到. 因此沒有問題. 若是要用到這2個配置, 能夠考慮fork一份代碼出來改.memcached
ngx_http_upstream_dynamic_servers.c:260測試
#if nginx_version >= 1007002 us->name = u.url; #endif us->addrs = u.addrs; us->naddrs = u.naddrs; us->weight = weight; us->max_fails = max_fails; us->fail_timeout = fail_timeout; return NGX_CONF_OK;
ngx_http_upstream_server_t:
typedef struct { ngx_str_t name; ngx_addr_t *addrs; ngx_uint_t naddrs; ngx_uint_t weight; ngx_uint_t max_fails; time_t fail_timeout; ngx_str_t id; ngx_str_t host; unsigned down:1; unsigned backup:1; } ngx_http_upstream_server_t;
ngx_http_upstream.c:5610
us->name = u.url; us->addrs = u.addrs; us->naddrs = u.naddrs; us->host = u.host; us->weight = weight; us->max_fails = max_fails; us->fail_timeout = fail_timeout; us->id = id; return NGX_CONF_OK;
由於nginx-upstream-dynamic-servers須要隨着nginx/tengine版本升級而維護server directive, 因此這裏提一下測試.
https://github.com/alibaba/tengine/wiki/How-to-test
diff --git a/tests/nginx-tests/nginx-tests/upstream.t b/tests/nginx-tests/nginx-tests/upstream.t index debbf5d..5dd670b 100644 --- a/tests/nginx-tests/nginx-tests/upstream.t +++ b/tests/nginx-tests/nginx-tests/upstream.t @@ -37,8 +37,8 @@ http { %%TEST_GLOBALS_HTTP%% upstream u { - server 127.0.0.1:8081 max_fails=3 fail_timeout=10s; - server 127.0.0.1:8082 max_fails=3 fail_timeout=10s; + server 127.0.0.1:8081 max_fails=3 fail_timeout=10s resolve; + server 127.0.0.1:8082 max_fails=3 fail_timeout=10s resolve; }
~/git/tengine/tests(52fff0e*) » TEST_NGINX_BINARY=/usr/sbin/nginx prove -r nginx-tests ... nginx-tests/nginx-tests/upstream.t ........................... ok nginx-tests/nginx-tests/upstream_hash.t ...................... ok nginx-tests/nginx-tests/upstream_hash_memcached.t ............ skipped: Cache::Memcached not installed nginx-tests/nginx-tests/upstream_ip_hash.t ................... skipped: no realip available nginx-tests/nginx-tests/upstream_least_conn.t ................ ok nginx-tests/nginx-tests/upstream_zone_ssl.t .................. skipped: no http_ssl available nginx-tests/nginx-tests/userid.t ............................. 1/34 skip() needs to know $how_many tests are in the block at nginx-tests/nginx-tests/userid.t line 185 ...
Use nginx variables/jdomain 沒法和其它nginx-upstream-module很好地配合使用, 不推薦在要求較高的產品中使用.nginx-upstream-dynamic-servers/tengine ngx_http_upstream_dynamic 能夠按實際狀況使用.