ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { ngx_url_t u; ngx_uint_t i, j, n, w, color; ngx_uint_t dyn_resolve = 0; ngx_http_upstream_server_t *server; ngx_http_upstream_rr_peers_t *peers, *backup; u_char addr6[NGX_INET6_ADDRSTRLEN]; us->peer.init = ngx_http_upstream_init_round_robin_peer; if (us->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; } if (n == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no servers in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->weighted = (w != n); peers->total_weight = w; peers->name = &us->host; n = 0; color = 1; for (i = 0; i < us->servers->nelts; i++) { if (server[i].backup) { continue; } #if (NGX_HAVE_INET6) dyn_resolve = (ngx_inet6_addr(server[i].host.data, server[i].host.len, addr6) == NGX_ERROR) ? 1 : 0; if (dyn_resolve) /* host is not an ipv6 address, check ipv4 */ #endif { dyn_resolve = (ngx_inet_addr(server[i].host.data, server[i].host.len) == INADDR_NONE) ? 1 : 0; } for (j = 0; j < server[i].naddrs; j++) { peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; peers->peer[n].socklen = server[i].addrs[j].socklen; peers->peer[n].name = server[i].addrs[j].name; peers->peer[n].host = server[i].host; peers->peer[n].weight = server[i].weight; peers->peer[n].effective_weight = server[i].weight; peers->peer[n].current_weight = 0; peers->peer[n].max_fails = server[i].max_fails; peers->peer[n].fail_timeout = server[i].fail_timeout; peers->peer[n].down = server[i].down; peers->peer[n].color = color; peers->peer[n].dyn_resolve = dyn_resolve; #if (NGX_HTTP_UPSTREAM_CHECK) if (!server[i].down) { peers->peer[n].check_index = ngx_http_upstream_check_add_peer(cf, us, &server[i].addrs[j]); } else { peers->peer[n].check_index = (ngx_uint_t) NGX_ERROR; } #endif n++; } color++; } us->peer.data = peers; /* backup servers */ 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; } if (n == 0) { return NGX_OK; } backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (backup == NULL) { return NGX_ERROR; } peers->single = 0; backup->single = 0; backup->number = n; backup->weighted = (w != n); backup->total_weight = w; backup->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { if (!server[i].backup) { continue; } #if (NGX_HAVE_INET6) dyn_resolve = (ngx_inet6_addr(server[i].host.data, server[i].host.len, addr6) == NGX_ERROR) ? 1 : 0; if (dyn_resolve) /* host is not an ipv6 address, check ipv4 */ #endif { dyn_resolve = (ngx_inet_addr(server[i].host.data, server[i].host.len) == INADDR_NONE) ? 1 : 0; } for (j = 0; j < server[i].naddrs; j++) { backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; backup->peer[n].socklen = server[i].addrs[j].socklen; backup->peer[n].name = server[i].addrs[j].name; backup->peer[n].host = server[i].host; backup->peer[n].weight = server[i].weight; backup->peer[n].effective_weight = server[i].weight; backup->peer[n].current_weight = 0; backup->peer[n].max_fails = server[i].max_fails; backup->peer[n].fail_timeout = server[i].fail_timeout; backup->peer[n].down = server[i].down; backup->peer[n].color = color; backup->peer[n].dyn_resolve = dyn_resolve; #if (NGX_HTTP_UPSTREAM_CHECK) if (!server[i].down) { backup->peer[n].check_index = ngx_http_upstream_check_add_peer(cf, us, &server[i].addrs[j]); } else { backup->peer[n].check_index = (ngx_uint_t) NGX_ERROR; } #endif n++; } color++; } peers->next = backup; return NGX_OK; } /* an upstream implicitly defined by proxy_pass, etc. */ if (us->port == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no port in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } ngx_memzero(&u, sizeof(ngx_url_t)); u.host = us->host; u.port = us->port; if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "%s in upstream \"%V\" in %s:%ui", u.err, &us->host, us->file_name, us->line); } return NGX_ERROR; } n = u.naddrs; peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->weighted = 0; peers->total_weight = n; peers->name = &us->host; #if (NGX_HAVE_INET6) dyn_resolve = (ngx_inet6_addr(u.host.data, u.host.len, addr6) == NGX_ERROR) ? 1 : 0; if (dyn_resolve) /* host is not an ipv6 address, check ipv4 */ #endif { dyn_resolve = (ngx_inet_addr(u.host.data, u.host.len) == INADDR_NONE) ? 1 : 0; } for (i = 0; i < u.naddrs; i++) { peers->peer[i].sockaddr = u.addrs[i].sockaddr; peers->peer[i].socklen = u.addrs[i].socklen; peers->peer[i].name = u.addrs[i].name; peers->peer[i].host = u.host; peers->peer[i].weight = 1; peers->peer[i].effective_weight = 1; peers->peer[i].current_weight = 0; peers->peer[i].max_fails = 1; peers->peer[i].fail_timeout = 10; #if (NGX_HTTP_UPSTREAM_CHECK) peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR; #endif peers->peer[i].color = 0; peers->peer[i].dyn_resolve = dyn_resolve; } us->peer.data = peers; /* implicitly defined upstream has no backup servers */ return NGX_OK; }
ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) { ngx_url_t u; ngx_uint_t i, j, n, w; ngx_http_upstream_server_t *server; ngx_http_upstream_rr_peers_t *peers, *backup; us->peer.init = ngx_http_upstream_init_round_robin_peer; if (us->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; } if (n == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no servers in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->weighted = (w != n); peers->total_weight = w; peers->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { for (j = 0; j < server[i].naddrs; j++) { if (server[i].backup) { continue; } peers->peer[n].sockaddr = server[i].addrs[j].sockaddr; peers->peer[n].socklen = server[i].addrs[j].socklen; peers->peer[n].name = server[i].addrs[j].name; peers->peer[n].id = server[i].id; peers->peer[n].max_fails = server[i].max_fails; peers->peer[n].fail_timeout = server[i].fail_timeout; peers->peer[n].down = server[i].down; peers->peer[n].weight = server[i].weight; peers->peer[n].effective_weight = server[i].weight; peers->peer[n].current_weight = 0; #if (NGX_HTTP_UPSTREAM_CHECK) if (!server[i].down) { peers->peer[n].check_index = ngx_http_upstream_check_add_peer(cf, us, &server[i].addrs[j]); } else { peers->peer[n].check_index = (ngx_uint_t) NGX_ERROR; } #endif n++; } } us->peer.data = peers; ngx_sort(&peers->peer[0], (size_t) n, sizeof(ngx_http_upstream_rr_peer_t), ngx_http_upstream_cmp_servers); /* backup servers */ 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; } if (n == 0) { return NGX_OK; } backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (backup == NULL) { return NGX_ERROR; } peers->single = 0; backup->single = 0; backup->number = n; backup->weighted = (w != n); backup->total_weight = w; backup->name = &us->host; n = 0; for (i = 0; i < us->servers->nelts; i++) { for (j = 0; j < server[i].naddrs; j++) { if (!server[i].backup) { continue; } backup->peer[n].sockaddr = server[i].addrs[j].sockaddr; backup->peer[n].socklen = server[i].addrs[j].socklen; backup->peer[n].name = server[i].addrs[j].name; backup->peer[n].id = server[i].id; backup->peer[n].weight = server[i].weight; backup->peer[n].effective_weight = server[i].weight; backup->peer[n].current_weight = 0; backup->peer[n].max_fails = server[i].max_fails; backup->peer[n].fail_timeout = server[i].fail_timeout; backup->peer[n].down = server[i].down; #if (NGX_HTTP_UPSTREAM_CHECK) if (!server[i].down) { backup->peer[n].check_index = ngx_http_upstream_check_add_peer(cf, us, &server[i].addrs[j]); } else { backup->peer[n].check_index = (ngx_uint_t) NGX_ERROR; } #endif n++; } } peers->next = backup; ngx_sort(&backup->peer[0], (size_t) n, sizeof(ngx_http_upstream_rr_peer_t), ngx_http_upstream_cmp_servers); return NGX_OK; } /* an upstream implicitly defined by proxy_pass, etc. */ if (us->port == 0 && us->default_port == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no port in upstream \"%V\" in %s:%ui", &us->host, us->file_name, us->line); return NGX_ERROR; } ngx_memzero(&u, sizeof(ngx_url_t)); u.host = us->host; u.port = (in_port_t) (us->port ? us->port : us->default_port); if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "%s in upstream \"%V\" in %s:%ui", u.err, &us->host, us->file_name, us->line); } return NGX_ERROR; } n = u.naddrs; peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t) + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1)); if (peers == NULL) { return NGX_ERROR; } peers->single = (n == 1); peers->number = n; peers->weighted = 0; peers->total_weight = n; peers->name = &us->host; for (i = 0; i < u.naddrs; i++) { peers->peer[i].sockaddr = u.addrs[i].sockaddr; peers->peer[i].socklen = u.addrs[i].socklen; peers->peer[i].name = u.addrs[i].name; peers->peer[i].id.len = 0; peers->peer[i].id.data = NULL; peers->peer[i].weight = 1; peers->peer[i].effective_weight = 1; peers->peer[i].current_weight = 0; peers->peer[i].max_fails = 1; peers->peer[i].fail_timeout = 10; #if (NGX_HTTP_UPSTREAM_CHECK) peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR; #endif } us->peer.data = peers; /* implicitly defined upstream has no backup servers */ return NGX_OK; }