upstream指令及负载均衡方式

帅比萌擦擦* 提交于 2019-12-06 13:03:51

UPSTREAM

语法: upstream name { ... }
默认值:
上下文: http

Defines a group of servers. Servers can listen on different ports. In addition, servers listening on TCP and UNIX-domain sockets can be mixed.

定义一组服务器。 这些服务器可以监听不同的端口。 而且,监听TCP和UNIX域套接字的服务器可以混用。

Example:

upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;

    server backup1.example.com  backup;
}

By default, requests are distributed between the servers using a weighted round-robin balancing method. In the above example, each 7 requests will be distributed as follows: 5 requests go to backend1.example.com and one request to each of the second and third servers. If an error occurs during communication with a server, the request will be passed to the next server, and so on until all of the functioning servers will be tried. If a successful response could not be obtained from any of the servers, the client will receive the result of the communication with the last server.

默认情况下,nginx按加权轮转的方式将请求分发到各服务器。 在上面的例子中,每7个请求会通过以下方式分发: 5个请求分到backend1.example.com, 一个请求分到第二个服务器,一个请求分到第三个服务器。 与服务器通信的时候,如果出现错误,请求会被传给下一个服务器,直到所有可用的服务器都被尝试过。 如果所有服务器都返回失败,客户端将会得到最后通信的那个服务器的(失败)响应结果。

服务器地址

语法: server address [parameters];
默认值:
上下文: upstream

Defines the address and other parameters of a server. The address can be specified as a domain name or IP address, with an optional port, or as a UNIX-domain socket path specified after the “unix:” prefix. If a port is not specified, the port 80 is used. A domain name that resolves to several IP addresses defines multiple servers at once. 

定义服务器的地址 address 和其他参数 parameters 。 地址可以是域名或者IP地址,端口是可选的,或者是指定“unix:”前缀的UNIX域套接字的路径。如果没有指定端口,就使用80端口。 如果一个域名解析到多个IP,本质上是定义了多个server。

你可以定义下面的参数:

  • weight = number 设定服务器的权重,默认是1。
  • max_conns = number 限制模拟激活连接到代理服务器的最大数量,默认值是0,意味着没有限制。如果服务器组没有定居在共享内存中,这个限制对每个worker进程都起作用。
  • max_fails=number 设定Nginx在 fail_time 参数定义的时间段内,与服务器通信的尝试失败的次数。如果失败的次数达到此值,Nginx就认为服务器不可用。在下一个fail_timeout时间段,服务器不会再被尝试。 失败的尝试次数默认是1。设为0就会停止统计尝试次数,认为服务器是一直可用的。你可以通过指令proxy_next_upstream、 fastcgi_next_upstream和memcached_next_upstream来配置什么是失败的尝试。
  • fail_timeout=time设定两个: 1, 统计失败尝试次数的时间段。在这段时间中,服务器失败次数达到指定的尝试次数,服务器就被认为不可用。2, 服务器被认为不可用的时间段。默认情况下,该超时时间是10秒。

  • backup 标记为备用服务器。当主服务器不可用以后,请求会被传给这些服务器。这个参数不能和 hash, ip_hash以及随机负载均衡方式一起使用

  • down 标记服务器永久不可用,可以跟ip_hash指令一起使用。

 哈希Key

语法 hash key [consistent];
默认值
上下文 upstream

This directive appeared in version 1.7.2. 这个之类在1.7.2版本中出现。

Specifies a load balancing method for a server group where the client-server mapping is based on the hashed key value. The key can contain text, variables, and their combinations. Note that adding or removing a server from the group may result in remapping most of the keys to different servers. The method is compatible with the Cache::Memcached Perl library.

它指明了当服务组的 客户端-服务器 按照 用key哈希过之后所产生的value值 来做匹配时的负载均衡方式。key 可以含有 文本,变量以及他们的组合。注意,增加或者从服务组中移除一个服务器可能会导致 绝大多数的 key 重新映射匹配到不同的服务器。这个方式和 Cache::Memcached Perl库兼容。

If the consistent parameter is specified, the ketama consistent hashing method will be used instead. The method ensures that only a few keys will be remapped to different servers when a server is added to or removed from the group. This helps to achieve a higher cache hit ratio for caching servers. The method is compatible with the Cache::Memcached::Fast Perl library with the ketama_points parameter set to 160.

如果指明了 一致性 参数, 将会使用ketama 一致性哈希方法。这个方法确保 当增加或者从服务组中移除一个服务器时,只有很少的一些 key 需要重新映射到不同的服务器。这帮助缓存服务器提高缓存命中率。这个方法和 Cache::Memcached::Fast Perl 库兼容,当 ketama_points 参数设为 160 时。

IP哈希负载均衡

语法 ip_hash;
默认值
上下文 upstream

Specifies that a group should use a load balancing method where requests are distributed between servers based on client IP addresses. The first three octets of the client IPv4 address, or the entire IPv6 address, are used as a hashing key. The method ensures that requests from the same client will always be passed to the same server except when this server is unavailable. In the latter case client requests will be passed to another server. Most probably, it will always be the same server as well.

指明 当请求是基于客户端的IP地址在服务器间进行分发的时候,服务器组应该使用的负载均衡方法。 IPv4地址的前三个字节或者IPv6的整个地址,会被用来作为一个哈希key。 这种方法可以确保从同一个客户端过来的请求,会被传给同一台服务器。除了当服务器被认为不可用的时候,这些客户端的请求会被传给其他服务器,而且很有可能也是同一台服务器。

从1.3.2和1.2.2版本开始支持IPv6地址。

如果其中一个服务器需要暂时移除,应该加上down参数。这样可以保留当前客户端IP地址散列分布。例子:

upstream backend {
    ip_hash;

    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
    server backend4.example.com;
}

从1.3.1和1.2.2版本开始,ip_hash的负载均衡方法才支持设置服务器权重值。

 

语法 keepalive connections;
默认值
上下文 upstream

这个指令出现在版本 1.1.4.

激活对上游服务器的连接进行缓存。

connections参数设置每个worker进程与后端服务器保持连接的最大数量。这些保持的连接会被放入缓存。 如果连接数大于这个值时,最久未使用的连接会被关闭。

需要注意的是,keepalive指令不会限制Nginx进程与上游服务器的连接总数。 新的连接总会按需被创建。 connections参数应该稍微设低一点,以便上游服务器也能处理额外新进来的连接。

配置memcached上游服务器连接keepalive的例子:

upstream memcached_backend {
    server 127.0.0.1:11211;
    server 10.0.0.2:11211;

    keepalive 32;
}

server {
    ...

    location /memcached/ {
        set $memcached_key $uri;
        memcached_pass memcached_backend;
    }

}

对于HTTP代理,proxy_http_version指令应该设置为“1.1”,同时“Connection”头的值也应被清空。

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

另外一种选择是,HTTP/1.0协议的持久连接也可以通过发送“Connection: Keep-Alive”头来实现。不过不建议这样用。

对于FastCGI的服务器,需要设置 fastcgi_keep_conn 指令来让连接keepalive工作:

upstream fastcgi_backend {
    server 127.0.0.1:9000;

    keepalive 8;
}

server {
    ...

    location /fastcgi/ {
        fastcgi_pass fastcgi_backend;
        fastcgi_keep_conn on;
        ...
    }
}

当使用的负载均衡方法不是默认的轮转法时,必须在keepalive 指令之前配置。

针对SCGI和uwsgi协议,还没有实现其keepalive连接的打算。

语法 keepalive_requests number;
默认值
keepalive_requests 100;
上下文 upstream

Sets the maximum number of requests that can be served through one keepalive connection. After the maximum number of requests is made, the connection is closed. 设置通过一次keepalive连接可以被服务的最大请求次数。超过最大次数后,连接将被关闭。

Closing connections periodically is necessary to free per-connection memory allocations. Therefore, using too high maximum number of requests could result in excessive memory usage and not recommended. 周期性地关闭连接对于释放连接内存分配空间是必要的。因此,设置非常高的最大请求次数可能会导致大量的内存使用,是不推荐的。

语法 keepalive_timeout timeout;
默认值
keepalive_timeout 60s;
上下文 upstream

This directive appeared in version 1.15.3.

 Sets a timeout during which an idle keepalive connection to an upstream server will stay open. 设置一个过期时间,在这个过期时间内,一个闲置的与上游服务器之间的keepalive连接将保持有效开通。

最少连接数负载均衡

Syntax: least_conn;
Default:
Context: upstream

This directive appeared in versions 1.3.1 and 1.2.2.

Specifies that a group should use a load balancing method where a request is passed to the server with the least number of active connections, taking into account weights of servers. If there are several such servers, they are tried in turn using a weighted round-robin balancing method.

它指明一个服务组应该使用一个负载均衡方法,在这个方法中,一个请求会被转发到,根据服务器的权重值,当前活动连接数量最少的那个服务器。如果有多个这样的服务器,它们会轮流尝试使用一个加权的轮转负载方式。

最少时间负载均衡

Syntax: least_time header | last_byte [inflight];
Default:
Context: upstream

This directive appeared in version 1.7.10.

Specifies that a group should use a load balancing method where a request is passed to the server with the least average response time and least number of active connections, taking into account weights of servers. If there are several such servers, they are tried in turn using a weighted round-robin balancing method. 它指明了一种负载均衡方式,当一个请求进来时,它将按照权重,被转发至拥有最低平均响应时间和最少活动连接数的服务器。如果有多个这样的服务器,它们会轮流尝试使用一个加权的轮转负载方式。

队列

语法 queue number [timeout=time];
默认值
上下文 upstream

This directive appeared in version 1.5.12.

If an upstream server cannot be selected immediately while processing a request, the request will be placed into the queue. The directive specifies the maximum number of requests that can be in the queue at the same time. If the queue is filled up, or the server to pass the request to cannot be selected within the time period specified in the timeout parameter, the 502 (Bad Gateway) error will be returned to the client.

The default value of the timeout parameter is 60 seconds.

When using load balancer methods other than the default round-robin method, it is necessary to activate them before the queue directive.

当处理一个请求时,如果没有一个上游服务器能被立即选出来处理这个请求时,这个请求将会被放入队列汇总。这个指令指明了在同一时间,这个队列中能放入的最大的请求次数。如果这个队列已经满了,或者那个将被转入的服务器不能被在 timeout 参数指明的时间段内被选出来,那么 502 (Bad Gateway) 错误将会被返回给客户端。timeout 参数的默认值是 60秒。

当使用负载均衡方式而不是默认的轮转方式时,应该在 queue 指令之前 就激活那些负载均衡方式。

随机负载均衡

Syntax: random [two [method]];
Default:
Context: upstream

This directive appeared in version 1.15.1.

Specifies that a group should use a load balancing method where a request is passed to a randomly selected server, taking into account weights of servers. 它指明了一种服务组的负载均衡方式,在这种方式下,一个请求将在考虑权重的情况下,被转发到一个随机选举出的服务器。

The optional two parameter instructs nginx to randomly select two servers and then choose a server using the specified method. The default method is least_conn which passes a request to a server with the least number of active connections. 可选的2个参数指明了nginx去随机选举2个服务器,然后使用指明的 method 去选择一个服务器。默认的 mothod 是 least_conn,也就是最少活动连接数的那个服务器。

The least_time method passes a request to a server with the least average response time and least number of active connections. If least_time=header is specified, the time to receive the response header is used. If least_time=last_byte is specified, the time to receive the full response is used. least_time 方式会转发请求到那个拥有最小平均响应时间和最少活动连接数的服务器。如果指明了 least_time = header,那么会使用接收到 response header的时间。如果指明的是 least_time = last_byte,将会使用 接收到 full reponse 全部响应的时间。

The  least_time method is available as a part of our  commercial subscription.

解析器 

语法 resolver address ... [valid=time] [ipv6=on|off] [status_zone=zone];
默认值
上下文 upstream

This directive appeared in version 1.17.5.

Configures name servers used to resolve names of upstream servers into addresses, for example:

用来将 上游服务器名称 解析成 地址 的配置名称服务器。

resolver 127.0.0.1 [::1]:5353;

The address can be specified as a domain name or IP address, with an optional port. If port is not specified, the port 53 is used. Name servers are queried in a round-robin fashion. 地址可以通过 域名或者IP地址来指明,可以带上一个可选的端口号。如果端口号未被指明,将使用端口号 53。名称服务器将通过轮转的方式被轮询。

By default, nginx will look up both IPv4 and IPv6 addresses while resolving. If looking up of IPv6 addresses is not desired, the ipv6=off parameter can be specified. 默认地,nginx 在解析时将同时查询IPv4 和 IPv6. 如果不需要查询IPv6,可以指明 ipv6=off.

By default, nginx caches answers using the TTL value of a response. An optional valid parameter allows overriding it:

resolver 127.0.0.1 [::1]:5353 valid=30s;

默认地,nginx缓存会使用一个响应中的TTL值来回答。可选的 valid 参数允许重写它

To prevent DNS spoofing, it is recommended configuring DNS servers in a properly secured trusted local network. 

The optional status_zone parameter enables collection of DNS server statistics of requests and responses in the specified zone.

This directive is available as part of our  commercial subscription.

解析时间 

Syntax: resolver_timeout time;
Default:
resolver_timeout 30s;
Context: upstream

This directive appeared in version 1.17.5.

Sets a timeout for name resolution, for example: 设置一个名称解析的超时时间,例如

resolver_timeout 5s;

This directive is available as part of our commercial subscription.

 

嵌入的变量

ngx_http_upstream_module模块支持以下嵌入变量:

  • $upstream_addr保存服务器的IP地址和端口或者是UNIX域套接字的路径。 在请求处理过程中,如果有多台服务器被尝试了,它们的地址会被拼接起来,以逗号隔开,比如: “192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock”。 如果在服务器之间通过“X-Accel-Redirect”头或者error_page有内部跳转,那么这些服务器组之间会以冒号隔开,比如:“192.168.1.1:80, 192.168.1.2:80, unix:/tmp/sock : 192.168.10.1:80, 192.168.10.2:80”
  • $upstream_response_time以毫秒的精度保留服务器的响应时间,(输出)单位是秒。 出现多个响应时,也是以逗号和冒号隔开。
  • $upstream_status保存服务器的响应代码。 出现多个响应时,也是以逗号和冒号隔开。
  • $upstream_http_...保存服务器的响应头的值。比如“Server”响应头的值可以通过
  • $upstream_http_server变量来获取。 需要注意的是只有最后一个响应的头会被保留下来。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!