problem with nginx round robin upstream
mdounin at mdounin.ru
Sat Sep 1 10:50:56 UTC 2012
On Thu, Aug 30, 2012 at 10:19:11AM +0300, Tsahi Asher wrote:
> I have a problem with the upstream round robin mechanism.
> in ngx_http_upstream.c ngx_http_upstream_server function the hostname that
> is added in the configuration file under upstream directive is added to the
> upstream server list.
> the function uses ngx_parse_url which in turn uses ngx_parse_inet_url that
> calls ngx_inet_resolve_host.
> ngx_inet_resolve_host tries to resolve the host name from the configuration
> file by calling gethostbyname. for each url gethostbyname return the list
> of ip's that are associated with this url and these ip's are added to the
> list of upstream servers.
> This results in a situation that if there are three servers defined in an
> upstream directive, each with an equal weight, but one of those server is
> associated with two ip's (for example internal and an external ip) then the
> round robin weight will not be equal for each server. The server which has
> two ip's will get a double weight.
Yes, this is how it works. Hostname which resolves to two ip
addresses effectively defines two upstream servers with identical
This is even explicitly documented, see
: ... A domain name that resolves to several IP addresses
: essentially defines multiple servers.
It's understood that this isn't exactly in line with historical
meaning of multiple ip addresses as addresses of the same
multihomed host in multiple networks.
It's much more common now to use multiple ip addresses for the
same name to mean multiple servers in a group though, and the
handling in the upstream module matches this usage pattern.
> i can add a log if required or if my explanation is not good enough.
> i saw that a url has a flag called one_addr that if is set to true will get
> resolved to a single ip only, but this flag is not used.
This flag is a minor optimization used when calling code isn't
capable of handling multiple ip addresses.
> adding the host ip address is one way to solve this, is there another way?
You have to either use ip address or a name which resolves to
exactly one ip address (if you want nginx to treat it as single
More information about the nginx-devel