nginx proxy_bind支持多个ip实现方法

需求

proxy_bind隶属于proxy_module,为向后端建立连接时的local ip。

我们以最新版nginx1.19.5为例,查看proxy_bind源码,发现proxy_bind配置指令只能接受1个或者2个参数。如下:

    { ngx_string("proxy_bind"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
      ngx_http_upstream_bind_set_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_proxy_loc_conf_t, upstream.local),
      NULL },

    { ngx_string("proxy_socket_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.socket_keepalive),
      NULL },

如果我们想使用proxy_bind配置多个ip支持ip数组怎么办呢???

这就需要我们修改nginx源码了。

修改源码

首先修改配置指令改成NGX_CONF_1MORE,然后修改ngx_http_upstream_bind_set_slot_array

ngx_string("proxy_bind"),

      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,

      ngx_http_upstream_bind_set_slot_array,

      NGX_HTTP_LOC_CONF_OFFSET,

      offsetof(ngx_http_proxy_loc_conf_t, upstream.local_array),

      NULL },

char *ngx_http_upstream_bind_set_slot_array(ngx_conf_t *cf, ngx_command_t *cmd,

    void *conf)

{

...

    ngx_http_upstream_local_array_t         **plocal, *local;

    plocal = (ngx_http_upstream_local_array_t **) (p + cmd->offset);

    if (*plocal != NGX_CONF_UNSET_PTR) {

        return "bind is duplicate";

    }

    value = cf->args->elts;

    // 建立local array

    local = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_local_array_t));

    *plocal = local;

    // 建立local peer addr

    local->addr = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addrs_t));

    // 建立addr array

    local->addr->addrs = ngx_array_create(cf->pool, 1, sizeof(ngx_addr_t));

    // 遍历所有的local ip,放进array中

    ......

        default:

            return NGX_CONF_ERROR;

        }

    }

...

}

在init_request中,将u→peer.local_array 赋值为u→conf→local_array

static void

ngx_http_upstream_init_request(ngx_http_request_t *r)

{

...

    u = r->upstream;

    u->peer.local_array = ngx_http_upstream_get_local_array(r, u->conf->local_array);

...

}

u→conf是通过不同的handler获得的,在nginx配置中常用的proxy_pass。

可以将这个赋值上去。

static ngx_int_t

ngx_http_proxy_handler(ngx_http_request_t *r)

{

...

    u = r->upstream;

    // 获取proxy的loc conf

    plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);

    // 获取对应的conf

    u->conf = &plcf->upstream;

...

}

plcf->upstream→upstream是真正的upstream_srv_conf。

是在proxy_pass中获取的。

static char *

ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

...

    

    plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);

...

}

END

最后抓包分析是否符合预期。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值