Created
September 15, 2013 16:01
-
-
Save gregvish/6572002 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/auto/modules b/auto/modules | |
index a78e785..30e1645 100644 | |
--- a/auto/modules | |
+++ b/auto/modules | |
@@ -376,6 +376,7 @@ if [ $HTTP_UPSTREAM_LEAST_CONN = YES ]; then | |
fi | |
if [ $HTTP_UPSTREAM_KEEPALIVE = YES ]; then | |
+ have=NGX_HTTP_UPSTREAM_KEEPALIVE . auto/have | |
HTTP_MODULES="$HTTP_MODULES $HTTP_UPSTREAM_KEEPALIVE_MODULE" | |
HTTP_SRCS="$HTTP_SRCS $HTTP_UPSTREAM_KEEPALIVE_SRCS" | |
fi | |
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c | |
index 5e62caa..9fee00b 100644 | |
--- a/src/http/modules/ngx_http_proxy_module.c | |
+++ b/src/http/modules/ngx_http_proxy_module.c | |
@@ -513,6 +513,22 @@ static ngx_command_t ngx_http_proxy_commands[] = { | |
#endif | |
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE) | |
+ { 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 }, | |
+#endif | |
+ | |
ngx_null_command | |
}; | |
@@ -2385,6 +2401,11 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) | |
* conf->redirects = NULL; | |
*/ | |
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE) | |
+ conf->upstream.default_keepalive = NGX_CONF_UNSET; | |
+ conf->upstream.default_keepalive_max_connections = NGX_CONF_UNSET_SIZE; | |
+#endif | |
+ | |
conf->upstream.store = NGX_CONF_UNSET; | |
conf->upstream.store_access = NGX_CONF_UNSET_UINT; | |
conf->upstream.buffering = NGX_CONF_UNSET; | |
@@ -2467,6 +2488,20 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
} | |
} | |
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE) | |
+ 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; | |
+ } | |
+ } | |
+#endif | |
+ | |
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..3723668 100644 | |
--- a/src/http/modules/ngx_http_upstream_keepalive_module.c | |
+++ b/src/http/modules/ngx_http_upstream_keepalive_module.c | |
@@ -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..4d54634 100644 | |
--- a/src/http/ngx_http.h | |
+++ b/src/http/ngx_http.h | |
@@ -51,6 +51,10 @@ typedef u_char *(*ngx_http_log_handler_pt)(ngx_http_request_t *r, | |
#if (NGX_HTTP_SSL) | |
#include <ngx_http_ssl_module.h> | |
#endif | |
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE) | |
+#include <ngx_http_upstream_keepalive_module.h> | |
+#endif | |
+ | |
struct ngx_http_log_ctx_s { | |
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c | |
index 45e2eb7..2a2ca1c 100644 | |
--- a/src/http/ngx_http_upstream.c | |
+++ b/src/http/ngx_http_upstream.c | |
@@ -931,6 +931,15 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx) | |
goto failed; | |
} | |
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE) | |
+ 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"); | |
+ } | |
+ } | |
+#endif | |
+ | |
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..7564050 100644 | |
--- a/src/http/ngx_http_upstream.h | |
+++ b/src/http/ngx_http_upstream.h | |
@@ -194,6 +194,12 @@ typedef struct { | |
#endif | |
ngx_str_t module; | |
+ | |
+#if (NGX_HTTP_UPSTREAM_KEEPALIVE) | |
+ ngx_uint_t default_keepalive; | |
+ ngx_uint_t default_keepalive_max_connections; | |
+ void *default_keepalive_cache; | |
+#endif | |
} ngx_http_upstream_conf_t; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment