From ea4654550ab021b5576c03b708079e3ce3e5d9ed Mon Sep 17 00:00:00 2001 From: Vladimir Homutov Date: Fri, 18 Oct 2019 16:33:15 +0300 Subject: [PATCH] Upstream: per-upstream resolver. The "resolver" and "resolver_timeout" directives can now be specified directly in the "upstream" block. --- src/http/ngx_http_upstream.c | 51 +++++++++++++++++++ src/http/ngx_http_upstream_round_robin.c | 12 ++--- src/stream/ngx_stream_upstream.c | 52 ++++++++++++++++++++ src/stream/ngx_stream_upstream_round_robin.c | 12 ++--- 4 files changed, 115 insertions(+), 12 deletions(-) diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index d090d1618..82a230024 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -169,6 +169,10 @@ static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r, static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +#if (NGX_HTTP_UPSTREAM_ZONE) +static char *ngx_http_upstream_resolver(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +#endif static ngx_int_t ngx_http_upstream_set_local(ngx_http_request_t *r, ngx_http_upstream_t *u, ngx_http_upstream_local_t *local); @@ -339,6 +343,24 @@ static ngx_command_t ngx_http_upstream_commands[] = { 0, NULL }, +#if (NGX_HTTP_UPSTREAM_ZONE) + + { ngx_string("resolver"), + NGX_HTTP_UPS_CONF|NGX_CONF_1MORE, + ngx_http_upstream_resolver, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + NULL }, + + { ngx_string("resolver_timeout"), + NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_upstream_srv_conf_t, resolver_timeout), + NULL }, + +#endif + ngx_null_command }; @@ -6434,6 +6456,32 @@ not_supported: } +#if (NGX_HTTP_UPSTREAM_ZONE) + +static char * +ngx_http_upstream_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_upstream_srv_conf_t *uscf = conf; + + ngx_str_t *value; + + if (uscf->resolver) { + return "is duplicate"; + } + + value = cf->args->elts; + + uscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); + if (uscf->resolver == NULL) { + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} + +#endif + + ngx_http_upstream_srv_conf_t * ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) { @@ -6515,6 +6563,9 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) uscf->line = cf->conf_file->line; uscf->port = u->port; uscf->no_port = u->no_port; +#if (NGX_HTTP_UPSTREAM_ZONE) + uscf->resolver_timeout = NGX_CONF_UNSET_MSEC; +#endif if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) { uscf->servers = ngx_array_create(cf->pool, 1, diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c index 5dbd4e626..304494b3c 100644 --- a/src/http/ngx_http_upstream_round_robin.c +++ b/src/http/ngx_http_upstream_round_robin.c @@ -97,15 +97,15 @@ ngx_http_upstream_init_round_robin(ngx_conf_t *cf, clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); - us->resolver = clcf->resolver; - us->resolver_timeout = clcf->resolver_timeout; + if (us->resolver == NULL) { + us->resolver = clcf->resolver; + } /* - * Without "resolver_timeout" in http{}, the value is unset. - * Even if we set it in ngx_http_core_merge_loc_conf(), it's - * still dependent on the module order and unreliable. + * Without "resolver_timeout" in http{} the merged value is unset. */ - ngx_conf_init_msec_value(us->resolver_timeout, 30000); + ngx_conf_merge_msec_value(us->resolver_timeout, + clcf->resolver_timeout, 30000); if (resolve && (us->resolver == NULL diff --git a/src/stream/ngx_stream_upstream.c b/src/stream/ngx_stream_upstream.c index be4f13016..6526d3c22 100644 --- a/src/stream/ngx_stream_upstream.c +++ b/src/stream/ngx_stream_upstream.c @@ -22,6 +22,11 @@ static char *ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +#if (NGX_STREAM_UPSTREAM_ZONE) +static char *ngx_stream_upstream_resolver(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +#endif + static void *ngx_stream_upstream_create_main_conf(ngx_conf_t *cf); static char *ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf); @@ -42,6 +47,24 @@ static ngx_command_t ngx_stream_upstream_commands[] = { 0, NULL }, +#if (NGX_STREAM_UPSTREAM_ZONE) + + { ngx_string("resolver"), + NGX_STREAM_UPS_CONF|NGX_CONF_1MORE, + ngx_stream_upstream_resolver, + NGX_STREAM_SRV_CONF_OFFSET, + 0, + NULL }, + + { ngx_string("resolver_timeout"), + NGX_STREAM_UPS_CONF|NGX_CONF_TAKE1, + ngx_conf_set_msec_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_upstream_srv_conf_t, resolver_timeout), + NULL }, + +#endif + ngx_null_command }; @@ -661,6 +684,32 @@ not_supported: } +#if (NGX_STREAM_UPSTREAM_ZONE) + +static char * +ngx_stream_upstream_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_stream_upstream_srv_conf_t *uscf = conf; + + ngx_str_t *value; + + if (uscf->resolver) { + return "is duplicate"; + } + + value = cf->args->elts; + + uscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1); + if (uscf->resolver == NULL) { + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; +} + +#endif + + ngx_stream_upstream_srv_conf_t * ngx_stream_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) { @@ -739,6 +788,9 @@ ngx_stream_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) uscf->line = cf->conf_file->line; uscf->port = u->port; uscf->no_port = u->no_port; +#if (NGX_STREAM_UPSTREAM_ZONE) + uscf->resolver_timeout = NGX_CONF_UNSET_MSEC; +#endif if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) { uscf->servers = ngx_array_create(cf->pool, 1, diff --git a/src/stream/ngx_stream_upstream_round_robin.c b/src/stream/ngx_stream_upstream_round_robin.c index e1903b3d2..5b5f20db7 100644 --- a/src/stream/ngx_stream_upstream_round_robin.c +++ b/src/stream/ngx_stream_upstream_round_robin.c @@ -104,15 +104,15 @@ ngx_stream_upstream_init_round_robin(ngx_conf_t *cf, cscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_core_module); - us->resolver = cscf->resolver; - us->resolver_timeout = cscf->resolver_timeout; + if (us->resolver == NULL) { + us->resolver = cscf->resolver; + } /* - * Without "resolver_timeout" in stream{}, the value is unset. - * Even if we set it in ngx_stream_core_merge_srv_conf(), it's - * still dependent on the module order and unreliable. + * Without "resolver_timeout" in stream{} the merged value is unset. */ - ngx_conf_init_msec_value(us->resolver_timeout, 30000); + ngx_conf_merge_msec_value(us->resolver_timeout, + cscf->resolver_timeout, 30000); if (resolve && (us->resolver == NULL