美文网首页我爱编程Nginx 配置参数
Module ngx_http_upstream_module

Module ngx_http_upstream_module

作者: 再回到从前 | 来源:发表于2017-03-21 12:39 被阅读0次

    以下内容来自官方文档

    http://nginx.org/en/docs/http/ngx_http_upstream_module.html,以及一些自己的理解(不见得正确!!!)。

    这个模块有很多指令,包含在如下:

      upstream;server;zone;state;hash;ip_hash;keepalive;ntlm;
      least_conn;least_time;health_check;match;queue;sticky;
      sticky_cookie_insert;

    包含内嵌变量如下:

    $upstream_addr;$upstream_bytes_received;$upstream_cache_status;
    $upstream_connect_time;$upstream_cookie_name;$upstream_header_time;
    $upstream_http_name;$upstream_response_length;$upstream_response_time;
    $upstream_status

    先来一个例子:

    upstream backend {
    server backend1.example.com       weight=5;  //比重为5,未设置的默认为1
    server backend2.example.com:8080;  //带端口的,未设置的默认为80
    server unix:/tmp/backend3;         //设置的是Unix的socket连接,比TCP的要更快一点
    server backup1.example.com:8080   backup;  //backup标识这它为备份后端,只有前面的挂掉了,才会启用备份后端
    server backup2.example.com:8080   backup;
    }

    server {
    location / {
    proxy_pass http://backend;  //这里使用了HTTP方式。
    }
    }

    另一个示例:

    resolver 10.0.0.1;
    upstreamdynamic{
    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

    Syntax:     upstream name { ... }
    Default:     —
    Context:     http

    定义一组server,每个server可监听不同的端口,而且可以混着监听TCP和Unix域 socket。

    如:

    upstream backend {
    server backend1.example.com weight=5;   //监听TCP,未设置端口,默认端口为80
    server 127.0.0.1:8080       max_fails=3 fail_timeout=30s; //监听TCP   max_fails 和 fail_timeout 在后面再讲。
    server unix:/tmp/backend3; //监听socket
    server backup1.example.com  backup;
    }

    默认情况下,Nginx使用轮询(round-robin)的方式来做server的负载平衡寻址,上面的例子中,server1比重占5,后面2个server比重各占1,也就是说平均下来每7个请求会有5个请求走到server1(概率上来讲,统计上来讲,实际上在某个特定长度的时间段里,不见得是完全符合这一的规律)。如果被请求的server发生了错误类似超时之类的,总之是无法提供服务了,Nginx就会寻找下一个服务(下一个服务还是按轮询来找,还是按配置顺序来找?),直到尝试所有server,只要有一个server能提供服务,Nginx就能对外提供服务,如果所有的server都不能提供服务,则Nginx也不能对外提供服务了。

    server

    Syntax:     server address [parameters];
    Default:     —
    Context:     upstream    //其实在HTTP,stream,upstream里都有自己的server指令,所有谈到server指令,首先要分清楚它的上下文(context)是什么。

    配置server的地址和参数,地址可以使用域名或IP,可以携带端口,端口是可选的,如果未携带端口,默认为80。地址也可以使用Unix域socket,路径以

    "unix:"为前缀。一个命名域名可以一次性解析多个server定义的IP(A domain name that resolves to

    several IP addresses defines multiple servers at once.)

    先来一个示例:

    upstream big_server_com {  //这里的 big_server_com 就是上面所说的 命名域名(A domain name)
    server127.0.0.3:8000 weight=5;
    server127.0.0.3:8001 weight=5;
    server192.168.0.1:8000;
    server192.168.0.1:8001;
    }

    server指令上可使用的参数:

    weight=number
    比重,设置后端的server的比重,在前面的示例里已经见过了。未设置默认为1。

    max_conns=number
    限制该server的最大活动(active)连接数,默认值为0,意思是无限制,如果server组没有运行在共享内存模式下,则限制应用于每个处理的worker(work的概念见Nginx核心模块的worker_processes指令)。如果Nginx启用了idle keepalive和multiple workers以及shared memory,则 活动连接总数+空闲连接可能会大于 max_conns 的值。(share memory和idle keepalive 参见后面的文档部分。)

    max_fails=number
    Nginx连接后端的server时,如果后端服务不可访问了,如何判断该服务不可用,这个参数是其中之一,另外一个是max_timeout,意思是指设定的超时时间段内,连接后端server失败时,最多尝试多少次,就判定该server为不可用了。默认次数为1,如果设置为0,则禁用判断服务不可用,即一直不断的尝试连接后端server。如下的这些指令另可能会考虑尝试连接:
    proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream, 和 memcached_next_upstream 指令。

    fail_timeout=time
    这是一个设置参数,一般跟上面的参数协同使用。该参数的含义:
    1:当连接后端server失败时,多长时间内可反复尝试连接后端server;
    2:一旦超过这个设置时间段,则判断该server的状态为不可用(unavailable );
    这个参数的默认值为10秒

    backup
    标识该server是备份server,当主server不可用时(主server可能是一组server),请求将被传送到backup的server上了,平时backup的server不接受处理请求。backup也可能是一组server。

    down
    标识该(组)server永久下线,不可用。

    Nginx Plus版本还提供了一些额外的参数共使用,未包含着开源版本里,所以也没法使用,略过,它们是:
    resolve;route;service;slow_start(这些都是upstream 上下文中server指令的参数);

    如果只有一个server,则 max_fails,fail_timeout,slow_start等参数都会被忽略,也即server永远不会被判为不可用。

    zone

    Syntax:     zone name [size];
    Default:     —
    Context:     upstream
    This directive appeared in version 1.9.0.

    设置共享内存区的名称和大小,并维持server组的配置和运行时状态在worker间是共享的。不同的server组可以共享同一个区,这种情况下,大小只需设置一次。

    示例:

    upstream dynamic {
    zone upstream_dynamic 64k;  //下面定义的server组共享命名为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;
    }

    state

    Syntax:     state file;
    Default:     —
    Context:     upstream
    This directive appeared in version 1.9.7.

    设置文件来保持动态配置组的状态。

    示例:

    state /var/lib/nginx/state/servers.conf; # path for Linux
    state /var/db/nginx/state/servers.conf;  # path for FreeBSD

    state一般用来限制列出server列表及这些server的参数,state设定的文件会在2种情况下被读取:

    1)初次解析Nginx配置文件的时候;
    2)修改upstream 配置的时候;
    应该避免直接修改文件内容,state指令不能和server指令一起使用。

    在Nginx被reload的时候,如果刚好做了更改,则会丢失更改。做二进制升级的时候也会导致丢失。

    hash

    Syntax:     hash key [consistent];
    Default:     —
    Context:     upstream
    This directive appeared in version 1.7.2.

    用在设置负载平衡(loadbalancing)中,客户端寻址server基于hash函数,这里设置hash的key值,key值可以包含文本,变量或二者的组合。注意,摘除掉一个server,会导致hash重新计算,也即原来的大多数的key可能会寻址到不同的server上。这个hash方法兼容Perl 的 Cache:Memcached 库。若有consistent参数,则Hash一致性将选择 ketama算法。这个算法保障,如果有server被摘除掉(从server group里),只有少数的key会重新映射到其他的server上去,也即大多数的key不受server摘除的影响,还走原来的server。这对提高缓存server命中率有很大帮助。这个方法跟Perl的Cache:Memcached:Fast库保持一致(该库的ketama_points参数须设置为160).

    upstream backend {
    hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
    }

    ip_hash

    Syntax:     ip_hash;
    Default:     —
    Context:     upstream

    也是设置load balancing的一种哈希方法。在寻址后端server时,根据客户端的IP来作为hash的key。使用的是IP4的前三位

    XXX.YYY.ZZZ.WWW,这里是XXX,也即XXX参与IP_HASH,后面的3端未参与。如果是IP6,则是整个IP6地址。这种方式确保同一客户端能被分配到相同的server上去,这对于后端有session的情况很有用(除非该后端的服务不可用)。

    如果某server临时性的不可用了,需要用 down 标识出来。以保留该server的客户端IP地址,也即再复活时,还能迅速接管它直接接管的客户端IP。

    示例

    upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
    server backend4.example.com;
    }

    keepalive

    Syntax:     keepalive connections;
    Default:     —
    Context:     upstream
    This directive appeared in version 1.1.4.

    维持upstream server的链接缓存。

    connections:设置维持链接的最大数量值,即使没有客户端连接,也保障Nginx跟upsteam

    server间的链接是活动的。注意,这里是指每一个worker。当连接数量超过最大值时,Nginx会把最近重复被利用次数最少的连接给关闭。说白了,就是Nginx跟后端server之间的连接池。

    尤其要注意的是,keepalive不限制Nginx

    worker与后端server之间的连接总数。keepalive设置的是空闲连接数,如果与后端server的连接不是空闲连接,一种有在使用,则可以一直增长连接数,直到打开连接数超过空闲连接数,并且这些连接也空闲下来了,才会去关闭连接。

    connections这个值要设置的小一点,小到什么程度呢?足以让upstream server出来新传入的连接。

    示例:

    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”。但不推荐这样使用。

    示例如下:

    upstream http_backend {
    server 127.0.0.1:8080;
    keepalive 16;
    }

    server {
    ...
    location /http/ {
    proxy_pass http://http_backend;
    proxy_http_version 1.0;
    proxy_set_header Connection "Keep-Alive";
    ...
    }
    }

    对于FastCGI server,需要设置fastcgi_keep_conn来维持长连接。

    upstream fastcgi_backend {
    server 127.0.0.1:9000;
    keepalive 8;
    }

    server {
    ...
    location /fastcgi/ {
    fastcgi_pass fastcgi_backend;
    fastcgi_keep_connon;
    ...
    }
    }

    注意:在使用非轮询算法的负载平衡时,有必要在keepalive指令前维持他们的连接(不太好理解)。

    ntlm

    Syntax:     ntlm;
    Default:     —
    Context:     upstream
    This directive appeared in version 1.9.2.

    允许代理请求使用NTLM认证,貌似不太常用,略过。

    示例:

    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 "";
    ...
    }
    }
    http {
    ...
    upstream exchange {
    zone exchange 64k;
    ntlm;
    server exchange1.example.com;
    server exchange2.example.com;
    }
    server {
    listen              443 ssl;
    ssl_certificate     /etc/nginx/ssl/company.com.crt;
    ssl_certificate_key /etc/nginx/ssl/company.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    location / {
    proxy_pass         https://exchange;
    proxy_http_version 1.1;
    proxy_set_header   Connection "";
    }
    }
    }

    least_conn

    Syntax:     least_conn;
    Default:     —
    Context:     upstream

    This directive appeared in versions 1.3.1 and 1.2.2.

    这是一种负载平衡的方法,最少连接数。在考虑server权重的情况下,负载平衡寻址找接受连接最少的server。如果符合条件的最少连接有多个server,则根据权重来轮询。

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

    least_time

    Syntax:     least_time header | last_byte [inflight];
    Default:     —
    Context:     upstream
    This directive appeared in version 1.7.10.

    这也是一种负载平衡的方法,平均响应时间最短。在考虑权重的情况下,寻址平均响应时间最短的server,如果符合条件的server有多个,则根据权重来轮询。

    如果设置了 header 参数,则$upstream_response_time 变量记录响应头部传输的时间;如果设置了last_byte,则$upstream_response_time变量记录response的整个过程的时间。

    upstream backend {
    least_time header;
    server backend1.example.com;
    server backend2.example.com;
    }

    health_check

    Syntax:     health_check [parameters];
    Default:     —
    Context:     location

    允许对server 组进行周期性的健康检查,服务可用性检查。支持如下可选参数:

    interval=time
    设置多长时间进行一次检查,默认是5秒。

    jitter=time
    设置检查时间间隔有一定的随机的延迟(抖动),默认没有延迟。

    fails=number
    设置多少次连续失败后,即判断该server为不可用,默认为1次。

    passes=number
    设定多少次连续成功访问到后端,即可判断该服务为可用,默认为1次。

    uri=uri
    设置健康检查的URL,默认为 "/"。

    location / {
    proxy_pass http://backend;
    health_check uri=/some/path;
    }

    mandatory
    设定是否要先强制检查server的可用性才认为健康,如果设置了这个,server的初始状态为“checking”,只有当health check完成后,才标识为health。如果该参数未设定,默认为不需要强制检查,server天生为health的。

    match=name
    指定match的配置响应应该通过的测试,以便通过健康检查。默认情况下,响应状态应该为2XX或3XX。2XX和3XX意味着服务是可用的。

    示例:

    match server_ok {
        status 200-399;
        header Content-Type = text/html;
        body !~ "maintenance mode";
    }
    http {
        match server_ok {
            status 200-399;
            header Content-Type = text/html;
            body !~ "maintenance mode";
        }
    server {
        location / {
        ......
        health_check match=server_ok;
        }
        }
    }

    这个示例中, 响应状态必须为200-399,Content-Type必须为text/html,响应体信息中不能含有"maintenance mode"

    port=number
    执行健康检查时,连接到server的端口,默认情况下为server的端口。

    示例:

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

    上面的配置,每5秒(默认)会对“/”路径进行一次检查,任何一次的检查请求失败,或状态不是2XX或3XX的,则认为该server的状态为 unhealthy,客户端的请求不会传输到 unhealthy 或 checking 状态的server上去。

    server group必须工作在共享内存模式下。

    如果一个server group 有多个健康检查的配置,任何一个健康检查的失败,都将导致该server状态为 unhealthy 。

    location / {
        proxy_pass http://backend;
        health_check interval=10 fails=3 passes=2;
    }

    http {
        ...
        match server_ok {
        status 200-399;
        body !~ "maintenance mode";
        }
        server {
            ...
            location / {
                proxy_pass http://backend;
                health_check match=server_ok;
            }
        }
    }

    match

    Syntax:     match name { ... }
    Default:     —
    Context:     http

    定义健康检查需要匹配的条件。可以参照上面的 health_check 来看。

    有如下使用方法:

    status 200;  //状态必须为200
    status ! 500; //状态码不能为500
    status 200 204; //状态码为200 或 400
    status ! 301 302; //状态码不能为301或302
    status 200-399; //状态码为200-399之间 都可以
    status ! 400-599; //状态码不能再 400-599之间
    status 301-303 307;//状态码在301-303之间或者307

    header Content-Type = text/html; //head 包含 Conten-type并且值为 text/html
    header Content-Type != text/html; //head 包含 Conten-Type,但值不能是 text/html
    header Connection ~ close; // head包含 Connection 参数,值为能匹配 "close"正则的内容。
    header Connection !~ close; //包含 Connection参数,不能匹配 "close"正则的内容
    header Host; //head 包含 Host 参数
    header ! X-Accel-Redirect; //head 不能有 X-Accel-Redirect

    body ~ "Welcome to nginx!"; //body 中能匹配含 “Welcome to nginx!"
    body !~ "Welcome to nginx!"; //body 中不能匹配含 "Welcome to nginx!"
    match 可以有多个配置,必须所有配置都通过检查,才能算是健康的,示例:(注意,不是在location 那里可以将match设置为多个match name)

    # 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

    Syntax:     queue number [timeout=time];
    Default:     —
    Context:     upstream
    This directive appeared in version 1.5.12.

    如果一个请求没有立刻被分配到一个server,那么该请求放到一个
    queue 里去。这个指令设置 queue 里能存放请求的最大值,如果 queue 满了,或者在 queue存放超过其超时设置时间还没被选出来传送给server,则会返回 502(Bad Gateway)错误给客户端。queue的超时时间默认为60秒。

    示例:

    upstream backend {
    server backend1.example.com  max_conns=3;
    server backend2.example.com;
    queue
    100 timeout=70;

    }

    upstream backend {
    zone backends 64k;
    queue
    750 timeout=30s;
    server webserver1.example.com max_conns=250;
    server webserver2.example.com max_conns=150;
    }

    sticky

    Syntax:     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];
    Default:     —
    Context:     upstream
    This directive appeared in version 1.5.7.

    设置session亲和性,这会使得每个客户端的请求会分发到一组server中的相同的server中去,即该客户端的上一个请求是哪个server处理的,下一个还分发给它来处理,保持会话的亲和性。设置会话亲和性有3种方法,cookie,route,learn。

    cookie

    使用cookie方法,则意味着派发server的依据是Nginx产生的cookie.cookie设创建,谁处理。首次客户端请求没有携带特定的cookie,则服务器端产出一个,并告诉客户端,带上这个cookie,下次直接来找我,下次请求含有该特定cookie,则直接派发给产出该cookie的服务器。

    upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    sticky cookie srv_id expires=1h domain=.example.com path=/;
    }

    尚未绑定到具体server的客户端请求会由负载平衡的方法来选择分派到哪个server,然后cookie会传给该server,如果被派分的server不能处理该请求,将选择一个新的server来处理它。第一个参数设置cookie的名称,其他参数有:

    expires:设置超时时间,max或具体的小时,天等,如果未设置,可能会导致用户超时。
    domain:cookie适用的域名。
    httponly:设置cookie 的 httponly属性。
    secure:设置cookie的secure属性。
    path:设置cookie的path属性。

    route

    使用route方法,后端server会在首次收到客户端的请求时分配一个route,该客户端所有后续的请求都会在cookie里或URI里携带这个route信息。这个信息将和upstream上下文里的"server"指令的"route"参数配合来识别后端server。如果server的route参数未设定,route名称将十六进制表示的IP地址和端口的MD5哈希,或Unix的socketpath,如果被派分的server不能处理该请求,将选择一个新的server来处理它。route的参数设定的变量可能包含路由信息,第一个非空变量用来匹配后端server。

    upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;
    sticky route $route_cookie $route_uri;
    }
    map $cookie_jsessionid $route_cookie {
    ~.+\.(?P\w+)$ $route; //从cookie里取
    }
    map $request_uri $route_uri {
    ~jsessionid=.+\.(?P\w+)$ $route; //从URI里取
    }
    upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;
    sticky route $route_cookie $route_uri;
    }

    也是在backend第一次response之后,会产生一个route信息,route信息通常会从cookie/URI信息中提取。这样Nginx会按照顺序搜索$route_cookie、$route_uri参数并选择第一个非空的参数用作route,而如果所有的参数都是空的,就使用上面默认的负载均衡算法决定请求分发给哪个backend。

    learn

    更为复杂和职能,Nginx分析upstream server的响应,并学习服务器正常的cookie,可能是业务上使用的。通常需要和zone搭配使用。

    upstream backend {
    server backend1.example.com:8080;
    server backend2.example.com:8081;
    sticky learn
    create=$upstream_cookie_examplecookie //创建一个叫 EXAMPLECOOKIE cookie。
    lookup=$cookie_examplecookie    //在请求里查找 EXAMPLECOOKIE cookie。
    zone=client_sessions:1m;    //session 存储在内存共享区,所以要配置zone,设置名称和大小。在64位的环境下,1M zone可以存储8000个session.timeout = 1h;  //在timeout时间段内,zone里的session如果没被访问过,则会被移除,默认的超时时间是10分钟。
    }

    sticky_cookie_insert

    Syntax:     sticky_cookie_insert name [expires=time] [domain=domain] [path=path];
    Default:     —
    Context:     upstream

    Nginx从V1.5.7后已抛弃该指令,使用上面的sticky cookie 等方式,故不表。

    相关文章

      网友评论

        本文标题:Module ngx_http_upstream_module

        本文链接:https://www.haomeiwen.com/subject/vhtgnttx.html