nginx中文文档-ngx_http_upstream_module

此页面版本:2016-06-08
ngx_http_upstream_module模块用于定义服务器组,可以在proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass以及 memcached_pass指令中引用。

示例配置

upstream backend {
    server backend1.example.com       weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

动态定义服务器组是商业版的一部分。

resolver 10.0.0.1;

upstream dynamic {
    zone upstream_dynamic 64k;

    server backend1.example.com      weight=5;
    server backend2.example.com:8080 fail_timeout=5s slow_start=30s;
    server 192.0.2.1                 max_fails=3;
    server backend3.example.com      resolve;
    server backend4.example.com      service=http resolve;

    server backup1.example.com:8080  backup;
    server backup2.example.com:8080  backup;
}

server {
    location / {
        proxy_pass http://dynamic;
        health_check;
    }
}

upstream

语法:upstream name { … }
默认:—
上下文:http

定义一个服务器组。服务器可以监听不同的端口。服务器可以混合的监听TCP和UNIX-domain socket。
示例:

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;
}

默认情况下,请求在服务器之间的分配使用带权重的轮询负载均衡方式。上面的例子中,每7个请求会按如下方式分配:5个请求分配到backend1.example.com,第二个和第三个服务器分别分配1个请求。如果在与一个服务器通信时发生了错误,请求将会传递给下一个服务器,直到所有的服务器都尝试了。如果从任何一个服务器都得不到成功的响应,客户端将会收到与最后一个服务器通信的结果。

server

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

定义服务器的地址和其他参数。地址可以指定为一个域名或IP地址与可选的端口号,或UNIX-domain socket路径指定在“unix:”前缀后面。如果没有指定端口,则使用80端口。如果域名解析成多个IP地址,一次定义多个服务器。
以下参数可以被定义:
weight=number
设置权重,默认为1.

max_fails=number
设置与服务器通信不成功的尝试次数,它发生在fail_timeout参数设置时间,服务器被认为是不可用的时间同样由fail_timeout参数设置。默认情况下,不成功的尝试次数为1.零值禁用记录尝试次数。什么被视为不成功的尝试由proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream 和 memcached_next_upstream指令定义。

fail_timeout=time
设置

  • 一个时间,在此期间指定次数的与服务器通信不成功尝试,将会使服务器被视为不可用状态。
  • 一个时间,这段时间内服务器被视为不可用。

backup
标记服务器是一个备份服务器。当主服务器不可用时,会将请求传给它。

down
标记服务器永久不可用。

以下参数商业版可用(商业版不进行翻译):
max_conns=number
limits the maximum number of simultaneous active connections to the proxied server (1.5.9). Default value is zero, meaning there is no limit.
When keepalive connections and multiple workers are enabled, the total number of connections to the proxied server may exceed the max_conns value.

resolve
monitors changes of the IP addresses that correspond to a domain name of the server, and automatically modifies the upstream configuration without the need of restarting nginx (1.5.12). The server group must reside in the shared memory.
In order for this parameter to work, the resolver directive must be specified in the http block. Example:

http {
    resolver 10.0.0.1;

    upstream u {
        zone ...;
        ...
        server example.com resolve;
    }
}

route=string
sets the server route name.

service=name
enables resolving of DNS SRV records and sets the service name (1.9.13). In order for this parameter to work, it is necessary to specify the resolve parameter for the server and specify a hostname without a port number.
If the service name does not contain a dot (“.”), then the RFC-compliant name is constructed and the TCP protocol is added to the service prefix. For example, to look up the _http._tcp.backend.example.com SRV record, it is necessary to specify the directive:

server backend.example.com service=http resolve;
If the service name contains one or more dots, then the name is constructed by joining the service prefix and the server name. For example, to look up the _http._tcp.backend.example.com and server1.backend.example.com SRV records, it is necessary to specify the directives:

server backend.example.com service=_http._tcp resolve;
server example.com service=server1.backend resolve;

Highest-priority SRV records (records with the same lowest-number priority value) are resolved as primary servers, the rest of SRV records are resolved as backup servers. If the backup parameter is specified for the server, high-priority SRV records are resolved as backup servers, the rest of SRV records are ignored.

slow_start=time
sets the time during which the server will recover its weight from zero to a nominal value, when unhealthy server becomes healthy, or when the server becomes available after a period of time it was considered unavailable. Default value is zero, i.e. slow start is disabled.

如果一个组里只有一个服务器max_fails, fail_timeout 和slow_start参数会忽略,这个服务器永远不会被视为不可用。

zone

语法:zone name [size]
默认:—
上下文:upstream
版本:1.9.0+

定义共享内存区域名称和大小,用于保存组配置和运行状态共工作进程之间共享。多个组可以共享相同的区域。这种情况下,仅指定一次大小就够了。
另外,在商业版本中,这些组允许在不重启nginx改变组的成员或修改一个服务器的配置。配置通过一个特殊的由upstream_conf处理的location访问。

state

语法:state file
默认:—
上下文:upstream
版本:1.9.7+

指定一个文件,用于保存动态配置组的状态。状态目前受列表中的服务器的参数限制。文件会在解析配置读取,每次upstream配置改变时更新。直接改变文件内容的行为应该避免。这个指令不能与server指令一同使用。
在配置重新加载和二进制升级过程中的改变会丢失。
该指令是商业版本的一部分。

hash

语法:hash key [consistent]
默认:—
上下文:upstream
版本:1.7.2+

为服务器组指定一个负载均衡的方法:客户端-服务器映射基于哈希键值。可以包含文本、变量以及它们的混合。注意,从组中添加或移除服务器可能会导致大部分的关键字都重新映射到不同的服务器。该方法与Cache::Memcached Perl库一致。
如果指定consistent参数,ketama一致性哈希算法将被使用。该方法确保当服务器添加到组或从组中删除时只有一少部分关键字会被映射到不同的服务器。这有助于为缓存服务器获得更高的缓存命中率。该方法与Cache::Memcached::Fast Perl库ketama_points参数设为60一致。

ip_hash

语法:ip_hash
默认:—
上下文:upstream

指定一个组使用负载均衡方法基于客户端IP地址分配服务器。客户端IPv4地址的前三字节或整个IPv6地址作为哈希关键字。该方法确保来自相同的客户端请求将总会被传给同一个服务器,除非服务器不可用。在最后一种情况下,客户端请求将会传给另一个服务器。大部分情况下,总会传给相同的服务器。
IPv6地址从1.3.2和1.2.2版本开始支持。
如果其中一个服务器需要临时的移除,需要标记为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

语法:keepalive connections
默认:—
上下文:upstream
版本:1.1.4+

为连接到上游服务器的连接开启缓存。
connections参数设置了每个工作进程保留的缓存连接到上游服务器空闲keepalive连接的最大数量。当这个数量被超过了,最近最少使用的连接将被关闭。
尤其要注意的是,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服务器,为keepalive连接工作需要设置fastcgi_keep_conn:

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连接的概念。

ntlm

语法:ntlm
默认:—
上下文:upstream
版本:1.9.2+

允许代理请求使用NTLM验证。上游连接需要客户端连接发送请求的“Authorization”字段值以“Negotiate”或“NTLM”开头。后面的客户端请求需要通过同一个上游连接进行代理,保持认证上下文。
为了使NTLM验证工作,需要启用与上游服务器的keepalive连接。proxy_http_version指令需要设置为“1.1”,“Connection”头域需要清空:

upstream http_backend {
    server 127.0.0.1:8080;

    ntlm;
}

server {
    ...

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

当使用除了轮询方式的负载均衡方法,需要在ntlm指令之前激活他们。
该指令为商业版本的一部分。

least_conn

语法:least_conn
默认:—
上下文:upstream
版本:1.3.1+1.2.2+

指定一个服务器组使用的负载均衡方法:将请求传递给活跃连接最少的服务器,考虑服务器权重。如果有很多这样的服务器,它们会使用带权重的轮询方法轮流尝试。

least_time

语法:least_time header | last_byte
默认:—
上下文:upstream
版本:1.7.10+

指定一个服务器组的负载均衡方法:请求传给最少平均响应时间和最少活动的连接的服务器,考虑权重。如果由多个这样的服务器,他们会使用有权重的轮询法轮流尝试。
如果指定了header参数,会使用收到响应头的时间。如果指定last_byte参数,使用完整响应收到的时间。
该指令为商业版本的一部分。

health_check

语法:health_check [parameters]
默认:—
上下文:location

启用指定location内服务器组的周期性健康检查。
支持下面的可选参数:
interval=time
设置两次连续的健康检查间隔,默认5秒。

fails=number
设置一个服务器的连续健康检查失败次数,超过这个次数,服务器会认为是不健康的,默认是1。

passes=number
设置一个服务器的连续检查通过次数,超过这个次数,服务器会被认为是健康的,默认是1。

uri=uri
定义用于进行健康检查的请求URI,默认是“/”。

match=name
指定match块配置响应需要通过的测试,默认响应应该是2xx或3xx状态码。

port=number
定义用于连接服务器进行健康检查的端口(1.9.7+),默认为服务器端口号。

例如

location / {
    proxy_pass http://backend;
    health_check;
}

将每5秒发送“/”到每个backend组服务器。如果任何通信错误或超时发生,或被代理服务器返回状态码不是2xx或3xx,健康检查失败,服务器会被认为是不健康。客户端请求不会发送到不健康的服务器。
健康检查可以配置为检测响应的状态码,存在指定的头和值,返回正文。测试使用match指令单独配置,通过match参数引用,例如:

http {
    server {
    ...
        location / {
            proxy_pass http://backend;
            health_check match=welcome;
        }
    }

    match welcome {
        status 200;
        header Content-Type = text/html;
        body ~ "Welcome to nginx!";
    }
}

这个配置说明了一个健康检查通过条件,响应一个健康检查请求应该成功,返回200状态码,正文类型为“text/html”并在正文中包含“Welcome to nginx!”。
服务器组必须在共享内存中。
如果同一个服务器组定义了多个健康检查,任何一个健康检查的失败都会使相应的服务器被认为是不健康的。
注意大多数用于健康检查的变量都是空的。
该指令是商业版本的一部分。

match

语法:match name { … }
默认:—
上下文:http

定义命名的测试设置,用于验证健康检查请求的响应。
下面可以在响应中测试:
status 200;
状态码200

status ! 500;
状态码不是500

status 200 204;
状态码200或204

status ! 301 302;
状态码既不是301也不是302

status 200-399;
状态码范围在200到399

status ! 400-599;
状态码范围不在400到599

status 301-303 307;
状态码是301、302、303或307

header Content-Type = text/html;
头包含“Content-Type”值为text/html

header Content-Type != text/html;
头包含“Content-Type”值不是text/html

header Connection ~ close;
头包含“Connection”值匹配正则表达式close

header Connection !~ close;
头包含“Connection”值不匹配正则表达式close

header Host;
头包含“Host”

header ! X-Accel-Redirect;
头缺少 “X-Accel-Redirect”

body ~ “Welcome to nginx!”;
正文匹配正则表达式“Welcome to nginx!”

body !~ “Welcome to nginx!”;
正文不匹配正则表达式“Welcome to nginx!”

如果指定了多个测试,只有所有测试都匹配,响应才匹配。
只有响应体的前256k会被检查。

例子:

# status is 200, content type is "text/html",
# and body contains "Welcome to nginx!"
match welcome {
    status 200;
    header Content-Type = text/html;
    body ~ "Welcome to nginx!";
}
# status is not one of 301, 302, 303, or 307, and header does not have "Refresh:"
match not_redirect {
    status ! 301-303 307;
    header ! Refresh;
}
# status ok and not in maintenance mode
match server_ok {
    status 200-399;
    body !~ "maintenance mode";
}

该指令为商业版本的一部分。

queue

语法:queue number [timeout=time]
默认:—
上下文:upstream
版本:1.5.12+

如果上游服务器在处理请求时不能立即选择,组中的服务器有些达到了最大连接数限制,请求将被放到队列里。该指令指定了同一时间可以放入队列的最大请求数。如果队列满了,或在timeout参数指定的时间内请求没有被选择,会返给客户端502错误码。
timeout参数默认为60秒。
该指令为商业版本的一部分。

sticky

语法:sticky cookie name [expires=time] [domain=domain] [httponly] [secure] [path=path]
sticky route $variable
sticky learn create=$variable lookup=$variable zone=name:size [timeout=time]
默认:—
上下文:upstream
版本:1.5.7+

开启粘性session,来自同一个客户端的请求将传给组中的同一个服务器。可用三种方式:
cookie
使用cookie方式时,由nginx生成指派服务器信息的HTTP cookie:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;

    sticky cookie srv_id expires=1h domain=.example.com path=/;
}

来自于一个客户端的请求必定发送到一个负载均衡方式配置的特定服务器。后面的请求带着这个cookie将会发到指派的服务器上。如果指派服务器不能处理请求,会选择新的服务器,就好像客户端没有绑定。
第一个参数设置了cookie的名字。附加的参数可以是下面的:
expires=time
设置浏览器应保持cookie的时间。特殊值max将使cookie在“31 Dec 2037 23:55:55 GMT”时间过期。如果参数没有指定,将会使cookie在浏览器会话结束时过期。

domain=domain
设置cookie的域名。

httponly
添加cookie的HttpOnly属性(1.7.11+)。

secure
添加cookie的secure属性(1.7.11+)。

path=path
定义设置cookie的路径。

如果任何参数省略,相应的cookie域不会设置。

route
当使用route方法时,被代理服务器在收到第一个请求后分配客户端路由。所有来自这个客户端的子请求在cookie或URI中都会携带路由信息。这个信息会与“route”参数比较,决定哪个服务器应该被代理。如果指派的服务器不能处理请求,一个新的服务器会被选中,如同请求中没有路由信息一样。
route方法参数定义变量可以包含路由信息。第一个非空的变量用于查找匹配的服务器。
例子:

map $cookie_jsessionid $route_cookie {
    ~.+\.(?P\w+)$ $route;
}

map $request_uri $route_uri {
    ~jsessionid=.+\.(?P\w+)$ $route;
}

upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;

    sticky route $route_cookie $route_uri;
}

这里,路由从请求cookie的“JSESSIONID”中取,如果没有,则从URI中取。

learn
当使用learn方法(1.7.1+),nginx分析上游服务器的响应,并学习通常服务器通过HTTP cookie发送的会话。

upstream backend {
   server backend1.example.com:8080;
   server backend2.example.com:8081;

   sticky learn
          create=$upstream_cookie_examplecookie
          lookup=$cookie_examplecookie
          zone=client_sessions:1m;
}

这个例子中,上游服务器通过响应中的cookie“EXAMPLECOOKIE”创建了一个会话。后续的请求带着这个cookie都会传给同一个服务器。如果服务器不能处理请求,会选择一个新的服务好像客户端没有绑定一样。
参数create和lookup指定了变量,分别表明新的会话如何创建,存在的会话如何查找。两个参数都可以定义超过一次,这时第一个非空变量将被使用。
会话保存在共享内存区域,名称和大小通过zone参数配置。1M的区域可以保存大约8000个会话,在64位系统上。在timeout参数指定的时间内会话没有被访问的将被从区域内删除。默认超时为10分钟。
该指令为商业版本的一部分。

sticky_cookie_insert

语法:sticky_cookie_insert name [expires=time] [domain=domain] [path=path]
默认:—
上下文:upstream

该指令从1.5.7版本开始废弃。等价的sticky指令的新语法为:
sticky cookie name [expires=time] [domain=domain] [path=path]

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


$upstream_addr
保存上游服务器的IP地址和端口号,或UNIX-domain socket路径。如果在处理请求时有多个服务器参与,它们的地址会用逗号分割,例如“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_cache_status
保存访问缓存响应的状态(0.8.3+)。状态可以是“MISS”, “BYPASS”, “EXPIRED”, “STALE”, “UPDATING”, “REVALIDATED”或“HIT”。


$upstream_connect_time
保留与上游服务器建立连接花费的时间(1.9.1+)。时间为秒数精确到毫秒。如果是SSL,包含握手的时间消耗。多个连接的时间通过逗号和冒号分割,就像$upstream_addr变量中的地址一样。


$upstream_cookie_name
指定名称的cookie通过“Set-Cookie”响应头从上游服务器发送(1.7.1+)。只有最后一个服务器响应的cookie会被保存。


$upstream_header_time
保存从上游服务器收到响应头的时间花费(1.7.10+)。时间为秒数精确到毫秒。多个响应的时间以逗号分割,就像$upstream_addr变量中的地址。


$upstream_http_name
保存服务器响应头。例如,“Server”响应头可以通过$upstream_http_server变量使用。转换头域名称到变量名称的规则与“$http_”前缀开头的变量相同。只有最后一个服务器响应头的头域会保存。


$upstream_response_length
保存从上游服务器收到的响应长度(0.7.27+)。长度单位为字节。多个响应的字节以逗号和冒号分割,就像$upstream_addr变量的地址一样。


$upstream_response_time
保存从上游服务器收到请求花费的时间。时间单位为秒,精确到毫秒。多个响应的时间以逗号和冒号分割,就像$upstream_addr变量的地址一样。


$upstream_status
保存从上游服务器收到响应的状态码。多个响应的状态码以逗号和冒号分割,就像$upstream_addr变量的地址一样。