mirror of
https://github.com/nginx/nginx.git
synced 2026-06-10 17:31:53 -04:00
Upstream: proxy_next_upstream_unique directive
Previously, nginx never picked the same peer twice during a proxy session. The proxy_next_upstream_unique directive allows to change this behavior and choose a peer from scratch each time. By default, the feature is enabled, which is the old behavior.
This commit is contained in:
parent
843cd60630
commit
73cd2e5bda
8 changed files with 43 additions and 10 deletions
|
|
@ -69,6 +69,7 @@ struct ngx_peer_connection_s {
|
|||
unsigned transparent:1;
|
||||
unsigned so_keepalive:1;
|
||||
unsigned down:1;
|
||||
unsigned unique:1;
|
||||
|
||||
/* ngx_connection_log_error_e */
|
||||
unsigned log_error:2;
|
||||
|
|
|
|||
|
|
@ -582,6 +582,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
|
|||
offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream_delay),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_next_upstream_unique"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream_unique),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_pass_header"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_array_slot,
|
||||
|
|
@ -3530,6 +3537,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||
conf->upstream.request_buffering = NGX_CONF_UNSET;
|
||||
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
|
||||
conf->upstream.force_ranges = NGX_CONF_UNSET;
|
||||
conf->upstream.next_upstream_unique = NGX_CONF_UNSET;
|
||||
|
||||
conf->upstream.local = NGX_CONF_UNSET_PTR;
|
||||
conf->upstream.socket_keepalive = NGX_CONF_UNSET;
|
||||
|
|
@ -3663,6 +3671,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->upstream.force_ranges,
|
||||
prev->upstream.force_ranges, 0);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.next_upstream_unique,
|
||||
prev->upstream.next_upstream_unique, 1);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->upstream.local,
|
||||
prev->upstream.local, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -308,7 +308,9 @@ found:
|
|||
ngx_http_upstream_rr_peer_unlock(hp->rrp.peers, peer);
|
||||
ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
|
||||
|
||||
hp->rrp.tried[n] |= m;
|
||||
if (pc->unique) {
|
||||
hp->rrp.tried[n] |= m;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
@ -713,7 +715,9 @@ found:
|
|||
n = best_i / (8 * sizeof(uintptr_t));
|
||||
m = (uintptr_t) 1 << best_i % (8 * sizeof(uintptr_t));
|
||||
|
||||
hp->rrp.tried[n] |= m;
|
||||
if (pc->unique) {
|
||||
hp->rrp.tried[n] |= m;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,9 @@ best_chosen:
|
|||
n = p / (8 * sizeof(uintptr_t));
|
||||
m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
|
||||
|
||||
rrp->tried[n] |= m;
|
||||
if (pc->unique) {
|
||||
rrp->tried[n] |= m;
|
||||
}
|
||||
|
||||
ngx_http_upstream_rr_peers_unlock(peers);
|
||||
|
||||
|
|
|
|||
|
|
@ -327,7 +327,9 @@ found:
|
|||
ngx_http_upstream_rr_peer_unlock(peers, peer);
|
||||
ngx_http_upstream_rr_peers_unlock(peers);
|
||||
|
||||
rrp->tried[n] |= m;
|
||||
if (pc->unique) {
|
||||
rrp->tried[n] |= m;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
@ -463,7 +465,9 @@ found:
|
|||
|
||||
ngx_http_upstream_rr_peers_unlock(peers);
|
||||
|
||||
rrp->tried[n] |= m;
|
||||
if (pc->unique) {
|
||||
rrp->tried[n] |= m;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -839,9 +839,10 @@ found:
|
|||
}
|
||||
|
||||
u->peer.start_time = ngx_current_msec;
|
||||
u->peer.unique = u->conf->next_upstream_unique;
|
||||
|
||||
if (u->conf->next_upstream_tries
|
||||
&& u->peer.tries > u->conf->next_upstream_tries)
|
||||
&& (!u->peer.unique || u->peer.tries > u->conf->next_upstream_tries))
|
||||
{
|
||||
u->peer.tries = u->conf->next_upstream_tries;
|
||||
}
|
||||
|
|
@ -1282,9 +1283,10 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
|
|||
ur->ctx = NULL;
|
||||
|
||||
u->peer.start_time = ngx_current_msec;
|
||||
u->peer.unique = u->conf->next_upstream_unique;
|
||||
|
||||
if (u->conf->next_upstream_tries
|
||||
&& u->peer.tries > u->conf->next_upstream_tries)
|
||||
&& (!u->peer.unique || u->peer.tries > u->conf->next_upstream_tries))
|
||||
{
|
||||
u->peer.tries = u->conf->next_upstream_tries;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ typedef struct {
|
|||
ngx_uint_t next_upstream;
|
||||
ngx_uint_t store_access;
|
||||
ngx_uint_t next_upstream_tries;
|
||||
ngx_flag_t next_upstream_unique;
|
||||
ngx_flag_t buffering;
|
||||
ngx_flag_t request_buffering;
|
||||
ngx_flag_t pass_request_headers;
|
||||
|
|
|
|||
|
|
@ -713,7 +713,7 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
|
|||
ngx_http_upstream_rr_peers_wlock(peers);
|
||||
|
||||
#if (NGX_HTTP_UPSTREAM_ZONE)
|
||||
if (peers->config && rrp->config != *peers->config) {
|
||||
if (pc->unique && peers->config && rrp->config != *peers->config) {
|
||||
goto busy;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -919,7 +919,9 @@ best_chosen:
|
|||
n = p / (8 * sizeof(uintptr_t));
|
||||
m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t));
|
||||
|
||||
rrp->tried[n] |= m;
|
||||
if (pc->unique) {
|
||||
rrp->tried[n] |= m;
|
||||
}
|
||||
|
||||
if (now - best->checked > best->fail_timeout) {
|
||||
best->checked = now;
|
||||
|
|
@ -1037,7 +1039,13 @@ ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
|
|||
|
||||
ngx_http_upstream_rr_peers_unlock(rrp->peers);
|
||||
|
||||
pc->tries = 0;
|
||||
if (pc->unique) {
|
||||
pc->tries = 0;
|
||||
|
||||
} else if (pc->tries) {
|
||||
pc->tries--;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue