nginx upstream回源代码完整分析

nginx回源函数

init_upstream函数是peer调用的时候使用的函数

初始化回源负载均衡算法ngx_http_upstream_init_round_robin函数

回源负载均衡算法函数如下:

ngx_http_upstream_init_round_robin

ngx_http_upstream_init_chash

ngx_http_upstream_init_dynamic

ngx_http_upstream_init_hash

ngx_http_upstream_init_ip_hash

ngx_http_upstream_init_keepalive

ngx_http_upstream_init_least_conn

ngx_http_upstream_session_sticky_init_upstream

在init main conf阶段调用init main conf方法。

upstream module只有main conf。

static ngx_http_module_t  ngx_http_upstream_module_ctx = {

    ngx_http_upstream_add_variables,       /* preconfiguration */

    NULL,                                  /* postconfiguration */

    ngx_http_upstream_create_main_conf,    /* create main configuration */

    ngx_http_upstream_init_main_conf,      /* init main configuration */

    NULL,                                  /* create server configuration */

    NULL,                                  /* merge server configuration */

    NULL,                                  /* create location configuration */

    NULL                                   /* merge location configuration */

};

ngx_http_upstream_init_round_robin函数

init_main_conf中调用ngx_http_upstream_init_round_robin来为rr初始化整个upstream下的upstream_srv_conf。

ngx_int_t

ngx_http_upstream_init_round_robin(ngx_conf_t *cf,

    ngx_http_upstream_srv_conf_t *us)

{

...

    us->peer.init = ngx_http_upstream_init_round_robin_peer;

    // 遍历servers获取数量、权重

    server = us->servers->elts;

        n = 0;

        w = 0;

        for (i = 0; i < us->servers->nelts; i++) {

            if (server[i].backup) {

                continue;

            }

            n += server[i].naddrs;

            w += server[i].naddrs * server[i].weight;

        }

    // 按照server数量pcalloc peers

    peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)

                              + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));

    // 赋值

    peers->single = (n == 1);

        peers->number = n;

        peers->weighted = (w != n);

        peers->total_weight = w;

        peers->name = &us->host;

        n = 0;

        peer = peers->peer;

    // 遍历两层循环

    for (i = 0; i < us->servers->nelts; i++) {

            if (server[i].backup) {

                continue;

            }

            for (j = 0; j < server[i].naddrs; j++) {

                // 将peer中赋值

            ......

// 健康检查

#if (NGX_HTTP_UPSTREAM_CHECK)

                if (!server[i].down) {

                    peer[n].check_index =

                        ngx_http_upstream_check_add_peer(cf, us,

                                                         &server[i].addrs[j]

            }

...

}

ngx_connect_peer函数

ngx_int_t

ngx_event_connect_peer(ngx_peer_connection_t *pc)

{

...

#ifdef CONFIG_NGX_NS

    struct ksock_vgw  kv;

    bzero(&kv, sizeof(struct ksock_vgw));

#endif

    // init round robin设置声明了get函数

    rc = pc->get(pc, pc->data);

    // 获取socket

    s = ngx_socket(pc->sockaddr->sa_family, SOCK_STREAM, 0);

    ......

    }

    int mss = 1460;

    if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &mss, sizeof(mss)) == -1 ) {

            ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, "setsockopt(TCP_MAXSEG) failed");

            goto failed;

    }

#endif

...

}

总结

在解析upstream{}server配置的时候放在us→servers中。

在init_round_robin建立整个upstream对应的peers,将所有servers对应监听地址都建立peer联系起来。

随后在create_round_robin_peer中,

rrp = r->upstream->peer.data;

rrp->peers = peers;

将peers和request联系起来,并将upstream_server级别的一些信息填充peer。

在ngx_http_upstream_get_round_robin_peer中,真正挑选出来peer,并且将peer对应的内容赋给peer_connection,发起ngx_event_connect,结束。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值