Skip to content

Instantly share code, notes, and snippets.

@gregvish
Created September 15, 2013 16:01
Show Gist options
  • Select an option

  • Save gregvish/6572002 to your computer and use it in GitHub Desktop.

Select an option

Save gregvish/6572002 to your computer and use it in GitHub Desktop.

Revisions

  1. gregvish created this gist Sep 15, 2013.
    255 changes: 255 additions & 0 deletions v3_default_keepalive_patch
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,255 @@
    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;