Created
September 11, 2013 15:39
-
-
Save gregvish/6525382 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c | |
index 5e62caa..e514d64 100644 | |
--- a/src/http/modules/ngx_http_proxy_module.c | |
+++ b/src/http/modules/ngx_http_proxy_module.c | |
@@ -513,6 +513,20 @@ static ngx_command_t ngx_http_proxy_commands[] = { | |
#endif | |
+ { ngx_string("proxy_upstream_default_keepalive"), | |
+ 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.default_keepalive), | |
+ NULL }, | |
+ | |
+ { ngx_string("proxy_upstream_default_keepalive_max_connections"), | |
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
+ ngx_conf_set_size_slot, | |
+ NGX_HTTP_LOC_CONF_OFFSET, | |
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.default_keepalive_max_connections), | |
+ NULL }, | |
+ | |
ngx_null_command | |
}; | |
@@ -2385,6 +2399,9 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) | |
* conf->redirects = NULL; | |
*/ | |
+ conf->upstream.default_keepalive = NGX_CONF_UNSET; | |
+ conf->upstream.default_keepalive_max_connections = NGX_CONF_UNSET_SIZE; | |
+ | |
conf->upstream.store = NGX_CONF_UNSET; | |
conf->upstream.store_access = NGX_CONF_UNSET_UINT; | |
conf->upstream.buffering = NGX_CONF_UNSET; | |
@@ -2467,6 +2484,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
} | |
} | |
+ ngx_conf_merge_uint_value(conf->upstream.default_keepalive, | |
+ prev->upstream.default_keepalive, 0); | |
+ | |
+ ngx_conf_merge_size_value(conf->upstream.default_keepalive_max_connections, | |
+ prev->upstream.default_keepalive_max_connections, 10); | |
+ | |
+ if (conf->upstream.default_keepalive) { | |
+ if (ngx_http_upstream_default_keepalive_init(cf, &(conf->upstream)) != NGX_CONF_OK) { | |
+ return NGX_CONF_ERROR; | |
+ } | |
+ } | |
+ | |
ngx_conf_merge_uint_value(conf->upstream.store_access, | |
prev->upstream.store_access, 0600); | |
diff --git a/src/http/modules/ngx_http_upstream_keepalive_module.c b/src/http/modules/ngx_http_upstream_keepalive_module.c | |
index eed1174..f4b99f8 100644 | |
--- a/src/http/modules/ngx_http_upstream_keepalive_module.c | |
+++ b/src/http/modules/ngx_http_upstream_keepalive_module.c | |
@@ -10,7 +10,7 @@ | |
#include <ngx_http.h> | |
-typedef struct { | |
+struct ngx_http_upstream_keepalive_srv_conf_s { | |
ngx_uint_t max_cached; | |
ngx_queue_t cache; | |
@@ -19,7 +19,7 @@ typedef struct { | |
ngx_http_upstream_init_pt original_init_upstream; | |
ngx_http_upstream_init_peer_pt original_init_peer; | |
-} ngx_http_upstream_keepalive_srv_conf_t; | |
+}; | |
typedef struct { | |
@@ -36,6 +36,8 @@ typedef struct { | |
ngx_event_set_peer_session_pt original_set_session; | |
ngx_event_save_peer_session_pt original_save_session; | |
#endif | |
+ | |
+ ngx_str_t host; | |
} ngx_http_upstream_keepalive_peer_data_t; | |
@@ -49,6 +51,9 @@ typedef struct { | |
socklen_t socklen; | |
u_char sockaddr[NGX_SOCKADDRLEN]; | |
+ char host[NGX_MAXHOSTNAMELEN]; | |
+ uint16_t host_len; | |
+ | |
} ngx_http_upstream_keepalive_cache_t; | |
@@ -184,6 +189,8 @@ ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r, | |
return NGX_ERROR; | |
} | |
+ kp->host = us->host; | |
+ | |
kp->conf = kcf; | |
kp->upstream = r->upstream; | |
kp->data = r->upstream->peer.data; | |
@@ -238,8 +245,9 @@ ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data) | |
c = item->connection; | |
if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr, | |
- item->socklen, pc->socklen) | |
- == 0) | |
+ item->socklen, pc->socklen) == 0 && | |
+ ngx_memn2cmp((u_char *) &item->host, (u_char *) kp->host.data, | |
+ item->host_len, kp->host.len) == 0) | |
{ | |
ngx_queue_remove(q); | |
ngx_queue_insert_head(&kp->conf->free, q); | |
@@ -345,6 +353,8 @@ ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data, | |
item->socklen = pc->socklen; | |
ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen); | |
+ item->host_len = kp->host.len; | |
+ ngx_memcpy(&item->host, kp->host.data, ngx_min(kp->host.len, NGX_MAXHOSTNAMELEN)); | |
if (c->read->ready) { | |
ngx_http_upstream_keepalive_close_handler(c->read); | |
@@ -537,3 +547,77 @@ invalid: | |
return NGX_CONF_ERROR; | |
} | |
+ | |
+char * | |
+ngx_http_upstream_default_keepalive_init(ngx_conf_t *cf, | |
+ ngx_http_upstream_conf_t *umcf) | |
+{ | |
+ ngx_uint_t i; | |
+ ngx_http_upstream_keepalive_cache_t *cached; | |
+ ngx_http_upstream_keepalive_srv_conf_t *kcf; | |
+ | |
+ kcf = ngx_pcalloc(cf->pool, | |
+ sizeof(ngx_http_upstream_keepalive_srv_conf_t)); | |
+ if (kcf == NULL) { | |
+ return NGX_CONF_ERROR; | |
+ } | |
+ | |
+ kcf->max_cached = umcf->default_keepalive_max_connections; | |
+ | |
+ cached = ngx_pcalloc(cf->pool, | |
+ sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached); | |
+ if (cached == NULL) { | |
+ return NGX_CONF_ERROR; | |
+ } | |
+ | |
+ ngx_queue_init(&kcf->cache); | |
+ ngx_queue_init(&kcf->free); | |
+ | |
+ for (i = 0; i < kcf->max_cached; i += 1) { | |
+ ngx_queue_insert_head(&kcf->free, &cached[i].queue); | |
+ cached[i].conf = kcf; | |
+ } | |
+ | |
+ umcf->default_keepalive_cache = kcf; | |
+ | |
+ return NGX_CONF_OK; | |
+} | |
+ | |
+ngx_int_t | |
+ngx_http_upstream_default_keepalive_adapt_peer(ngx_http_request_t *r, | |
+ ngx_http_upstream_resolved_t *ur) | |
+{ | |
+ ngx_http_upstream_keepalive_peer_data_t *kp; | |
+ ngx_http_upstream_keepalive_srv_conf_t *kcf; | |
+ | |
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
+ "default keepalive adapt peer"); | |
+ | |
+ kcf = r->upstream->conf->default_keepalive_cache; | |
+ | |
+ kp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_keepalive_peer_data_t)); | |
+ if (kp == NULL) { | |
+ return NGX_ERROR; | |
+ } | |
+ | |
+ kp->host = ur->host; | |
+ | |
+ kp->conf = kcf; | |
+ kp->upstream = r->upstream; | |
+ kp->data = r->upstream->peer.data; | |
+ kp->original_get_peer = r->upstream->peer.get; | |
+ kp->original_free_peer = r->upstream->peer.free; | |
+ | |
+ r->upstream->peer.data = kp; | |
+ r->upstream->peer.get = ngx_http_upstream_get_keepalive_peer; | |
+ r->upstream->peer.free = ngx_http_upstream_free_keepalive_peer; | |
+ | |
+#if (NGX_HTTP_SSL) | |
+ kp->original_set_session = r->upstream->peer.set_session; | |
+ kp->original_save_session = r->upstream->peer.save_session; | |
+ r->upstream->peer.set_session = ngx_http_upstream_keepalive_set_session; | |
+ r->upstream->peer.save_session = ngx_http_upstream_keepalive_save_session; | |
+#endif | |
+ | |
+ return NGX_OK; | |
+} | |
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h | |
index d4dc1bd..64cb6fe 100644 | |
--- a/src/http/ngx_http.h | |
+++ b/src/http/ngx_http.h | |
@@ -19,6 +19,7 @@ typedef struct ngx_http_cache_s ngx_http_cache_t; | |
typedef struct ngx_http_file_cache_s ngx_http_file_cache_t; | |
typedef struct ngx_http_log_ctx_s ngx_http_log_ctx_t; | |
typedef struct ngx_http_chunked_s ngx_http_chunked_t; | |
+typedef struct ngx_http_upstream_keepalive_srv_conf_s ngx_http_upstream_keepalive_srv_conf_t; | |
#if (NGX_HTTP_SPDY) | |
typedef struct ngx_http_spdy_stream_s ngx_http_spdy_stream_t; | |
@@ -36,6 +37,7 @@ typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r, | |
#include <ngx_http_script.h> | |
#include <ngx_http_upstream.h> | |
#include <ngx_http_upstream_round_robin.h> | |
+#include <ngx_http_upstream_keepalive_module.h> | |
#include <ngx_http_busy_lock.h> | |
#include <ngx_http_core_module.h> | |
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c | |
index 45e2eb7..39ad475 100644 | |
--- a/src/http/ngx_http_upstream.c | |
+++ b/src/http/ngx_http_upstream.c | |
@@ -931,6 +931,13 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx) | |
goto failed; | |
} | |
+ if (r->upstream->conf->default_keepalive) { | |
+ if (ngx_http_upstream_default_keepalive_adapt_peer(r, ur) != NGX_OK) { | |
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
+ "http upstream default keepalive: can't keepalive peer"); | |
+ } | |
+ } | |
+ | |
ngx_resolve_name_done(ctx); | |
ur->ctx = NULL; | |
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h | |
index 29ebf9b..c2fea48 100644 | |
--- a/src/http/ngx_http_upstream.h | |
+++ b/src/http/ngx_http_upstream.h | |
@@ -194,6 +194,10 @@ typedef struct { | |
#endif | |
ngx_str_t module; | |
+ | |
+ ngx_uint_t default_keepalive; | |
+ ngx_uint_t default_keepalive_max_connections; | |
+ ngx_http_upstream_keepalive_srv_conf_t *default_keepalive_cache; | |
} ngx_http_upstream_conf_t; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment