Nginx(十四) 配置文件详解 - 负载均衡(超详细)

        本篇文章主要讲ngx_http_upstream_module模块下各指令的使用方法。

1. upstream 上游服务器组/集群

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

        upstream指令定义了一个上游服务器组/集群,便于反向代理中的proxy_pass使用。服务器可以监听不同的端口。此外,监听 TCP 和 UNIX-domain 套接字的服务器可以混合使用。

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 unix:/tmp/backend3;
}

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

        默认情况下,请求在服务器之间的分配采用加权循环平衡法。在下面示例中,如果一共有 7 个,那么这7个请求将按如下方式进行分配: 其中前5个请求发送到 backend1.example.com,第二个和第三个服务器各收到一个请求。如果在与某台服务器通信时发生错误,请求将被转发到Next Server,依此类推,直到所有正常运行的服务器都被尝试过。如果无法从任何一个服务器获得成功响应,客户端将收到最后一个服务器的返回响应结果。

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

2. server 定义服务器

Syntax:    server address [parameters];
Default:    —
Context:    upstream

        定义服务器的address和其他参数。address可指定为域名或 IP 地址,端口可选,或在 "unix: "前缀后指定 UNIX-domain 套接字路径。如果未指定端口,则使用80端口。能解析到多个IP地址的域名可同时定义多个服务器。

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

        该指令还可配置以下几个可选参数:

  • weight=number:设置上游服务器的权重,默认值是1
  • max_conns=number:限制代理服务器的最大同时活动连接数。默认值为0,即没有限制。如果服务器组不在共享内存中,则限制对每个工作进程都有效。如果开启了 keepalive 长连接、多工作进程和共享内存,代理服务器的活动和空闲连接总数可能会超过 max_conns 值。
  • max_fails=number:设置转发请求的失败次数,默认值是1,表示失败1次就判断该服务器为不可用。设为0时,表示不校验失败次数。该参数与fail_timeout配合使用,如果连续转发给这台上游服务器的请求都失败,且次数达到该参数指定的值,则判定这台上游服务器在fail_timeout参数设定的时间段内为不可用,其它的请求在这段时间内不会转发给这台服务器。这里的请求失败,是由 proxy_next_upstream、fastcgi_next_upstream、uwsgi_next_upstream、sgi_next_upstream、memcached_next_upstream 和 grpc_next_upstream 指令来定义的。
  • fail_timeout=time:设置上游服务器的不可用时间,默认值是10s。当转发请求的失败次数达到指定值后,判断这台服务器在该参数设定的时间段内为不可用。
  • backup:将该服务器标记为备用服务器。当所有主服务器都不可用时,才会将请求转发给备用服务器。请注意,该参数不能与hash、ip_hash和random负载均衡指令一起使用,否则该参数配置失效。
  • down:将该服务器标记为永久不可用,只在使用ip_hash指令时才有用。
  • resolve:监控服务器域名对应的 IP 地址变化,并自动修改上游配置,无需重启 nginx (1.5.12)。服务器组必须位于共享内存中。为使该参数生效,必须在 http 块或相应的upstream块中指定resolve指令。
  • route=string:设置服务器路由名称。
  • service=name:启用 DNS SRV 记录解析并设置服务名称 (1.9.13)。为使该参数生效,必须为当前server的设置resolve参数,并指定一个不含端口号的Hostname。
  • slow_start=time:当不正常服务器变为正常,或者是被认为不可用的服务器在一段时间后变为可用时,该参数可设置将服务器权重从零恢复到额定值的时间。默认值为零,即禁用慢启动。该参数不能与hash、ip_hash和random负载均衡指令一起使用,否则该参数配置失效。
  • drain:让该服务器进入"draining"模式(1.13.6)。在这种模式下,只有绑定到服务器的请求才会代理到服务器。

3. zone 共享内存区

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

        定义共享内存区的name和size,该区域用于保存工作进程之间共享的组的配置和运行时状态。多个组可以共享同一个区域,在这种情况下,只需指定一次size即可。

        此外,无需重启Nginx就可修改群组成员身份或修改特定服务器的设置。

4. 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

        目前,该状态仅限于服务器列表及其参数。解析配置时会读取该文件,上游配置每次更改时都会更新该文件。应避免直接更改文件内容。该指令不能与server指令同时使用

5. ntlm 

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

        允许使用 NTLM Authentication代理请求。客户端一旦发送了请求头中带有 "Authorization"字段且对应值以 "Negotiate(协商)"或 "NTLM(NTLM)"开头的请求,那么该上游服务器就会与客户端进行连接绑定。以后的客户端请求将通过同一上游连接代理,并保持身份验证上下文。

        如果要使用默认轮循方法以外的负载均衡方法,对应指令必须在ntlm指令之前配置。

        为了使 NTLM Authentication 正常工作,必须启用上游服务器的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 "";
        ...
    }
}

6. queue 连接队列

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

        指定存放连接的队列大小。如果在处理请求时无法立即选择上游服务器,则将该请求放入一个队列中。该指令指定了队列中同时可容纳的最大请求数。

        如果队列已满,或在timeout参数指定时间内仍然无法为某一连接选择到上游服务器,则向客户端返回 502(Bad Gateway)错误。

        timeout 的默认值为 60 秒。

        如果要使用默认轮循方法以外的负载均衡方法,对应指令必须在queue指令之前配置。

7.长连接 keepalive

7.1 keepalive 限制长连接数量

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

        限制与上游服务器保持长连接的数量,这个长连接数量是由Nginx来管理的,不是TCP协议栈来管理。connections参数指定了每个工作进程最多可与上游服务器保持长连接的数量。当超过这个数量时,最近使用最少的连接将被关闭。

        需要特别注意的是,该指令并不限制nginx工作进程可以与上游服务器建立连接的总数,但connections参数应设置得足够小,以便上游服务器也能处理新建立的连接请求。

        如果要使用默认轮循方法以外的负载均衡方法,对应指令必须在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请求,如果要使用keepalive指令,必须配置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 "";
        ...
    }
}

        对于 FastCGI 服务器,需要设置 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;
        ...
    }
}

         SCGI 和 uwsgi 协议没有 keepalive 连接的概念。

7.2 keepalive_requests 限制最大请求数

Syntax:    keepalive_requests number;
Default:    keepalive_requests 1000;
Context:    upstream
This directive appeared in version 1.15.3.

        设置一个 keepalive 长连接可处理的最大请求数。请求次数达到上限后,连接将关闭。

        必须定期关闭连接以便于释放每个连接的内存分配。使用过高的最大请求数可能会导致内存使用过多,不建议使用。

7.3 keepalive_time 限制最长请求时间

Syntax:    keepalive_time time;
Default:    keepalive_time 1h;
Context:    upstream
This directive appeared in version 1.19.10.

        限制一个 keepalive 长连接处理请求的最长时间。达到该时间后,连接将在后续请求处理后关闭。

7.4 keepalive_timeout 限制空闲等待时间

Syntax:    keepalive_timeout timeout;
Default:    keepalive_timeout 60s;
Context:    upstream
This directive appeared in version 1.15.3.

        限制与上游服务器建立的长连接的最长空闲等待时间。超过这个时间,连接将关闭。

8.其它负载均衡法

8.1 hash 一致性哈希法

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

        其中client-server映射基于散列的key值。key值可以包含文本、变量及其组合。请注意,从服务器组中添加或删除服务器可能会导致大部分键值重新映射到不同的服务器上。该方法与 Cache::Memcached Perl 库兼容。

        哈希策略方法可以针对客户端访问的 URL 计算哈希值,对相同的 URL 请求,Nginx 可以因相同的哈希值而将其分配到同一后端服务器。

        如果指定了 consistent 参数,则将使用 ketama consistent 哈希方法。该方法可确保在将服务器添加到组中或从组中移除时,只有少数键会被重新映射到不同的服务器上。这有助于提高缓存服务器的缓存命中率。该方法与 Cache::Memcached::Fast Perl 库兼容,且 ketama_points 参数设置为 160。

        一致性哈希的优点是,可以使不同客户端的相似请求发送给同一被代理服务器,当被代理服务器为缓存服务器场景应用时,可以极大提高缓存的命中率。

        一致性哈希的缺点是,当上游服务器组中的节点数量发生变化时,将导致所有绑定被代理服务器的哈希值重新计算,影响整个集群的绑定关系,产生大量回源请求。

8.2 ip_hash ip哈希法

Syntax:    ip_hash;
Default:    —
Context:    upstream

        IP哈希(IP Hash)负载均衡策略根据客户端IP计算出哈希值,然后把请求分配给该数值对应的被代理服务器。客户端 IPv4 地址的前三个八位位组或整个 IPv6 地址将用作哈希密钥。该方法可确保来自同一客户端的请求始终被传递到同一服务器,除非该服务器不可用。在后一种情况下,客户端请求将被传递到另一个服务器。很可能也是同一个服务器。

        如果有一台服务器需要暂时从upstream中移除时,不能直接删除,而是使用down参数进行标识,用以确保转发策略的一惯性。

        在 1.3.1 和 1.2.2 版本之前,使用 ip_hash 负载平衡方法无法为服务器指定权重。

upstream backend {
    ip_hash;

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

8.3 least_conn 最少连接法

Syntax:    least_conn;
Default:    —
Context:    upstream
This directive appeared in versions 1.3.1 and 1.2.2.

        在考虑服务器权重的情况下,将请求传递给活动连接数最少的服务器。如果有多个这样的服务器,则使用加权循环平衡法依次尝试。

8.4 least_time 响应最短法

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

        在考虑服务器权重的情况下,将请求传递给平均响应时间最短、活动连接数最少的服务器。如果有多个这样的服务器,则使用加权循环平衡法依次尝试。 

        如果指定了header参数,则使用接收响应头的时间。

        如果指定了last_byte参数,则使用接收完整响应的时间。

        如果指定了 inflight 参数(1.11.6),则不完整的请求也会被考虑在内。

8.5 random 随机法

Syntax:    random [two [method]];
Default:    —
Context:    upstream
This directive appeared in version 1.15.1.

        在考虑服务器权重的情况下,将请求传递给随机选择的服务器。

        可选参数 two 表示 nginx 先随机选择两个服务器,然后再使用指定的 method 选择一个服务器。method 默认是 least_conn,将请求传递给活动连接数最少的服务器。method 也可以选择 least_time。

9. DNS服务器 resolver

9.1 resolver DNS服务器

Syntax:    resolver address ... [valid=time] [ipv4=on|off] [ipv6=on|off] [status_zone=zone];
Default:    —
Context:    upstream
This directive appeared in version 1.17.5.

        配置用于解析上游服务器域名的NDS服务器,便于动态解析域名。

        address:配置DNS服务器的域名或IP地址,端口可选。如未指定端口,则使用端口53。address可以配置多个,中间用空格隔开。DNS服务器以循环方式查询。

        [valid=time]:设置DNS解析信息的缓存时间,单位是秒,默认时间是DNS记录的TTL值。
        [ipv4=on|off]:设置解析域名时是否需要查找IPv4地址,默认情况下,nginx 在解析时会同时查找 IPv4 和 IPv6 地址。on表示需要,off表示不需要。
        [ipv6=on|off]:设置解析域名时是否需要查找IPv6地址,on表示需要,off表示不需要。

​resolver 11.11.11.11:54 127.0.0.1 [::1]:5353 valid=30s ipv6=off;

9.2 resolver_timeout DNS解析超时时间

Syntax:    resolver_timeout time;
Default:    resolver_timeout 30s;
Context:    upstream
This directive appeared in version 1.17.5.

        设置DNS解析超时时间,单位是秒,默认是30秒。可以缩短到10秒左右。 

10. sticky 亲和/粘性会话

Syntax:    sticky cookie name [expires=time] [domain=domain] [httponly] [samesite=strict|lax|none|$variable] [secure] [path=path];
                sticky route $variable ...;
                sticky learn create=$variable lookup=$variable zone=name:size [timeout=time] [header] [sync];
Default:    —
Context:    upstream
This directive appeared in version 1.5.7.

        启用亲和/粘性会话,使来自同一客户端的请求传递给一组服务器中的同一服务器。有三种方法可供选择:

  • 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 名称。cookie 值是 IP 地址和端口或 UNIX 域套接字路径的 MD5 哈希值的十六进制表示。但是,如果server指令指定了 "route"参数,cookie 值将是 "route"参数的值:

# 在这种情况下,"srv_id"的cookie值要么是 a,要么是 b。
upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;

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

        [expires=time]:设置浏览器保存 cookie 的时间。特殊值 max 会导致 cookie 在 "31 Dec 2037 23:55:55 GMT "过期。如果不指定该参数,cookie 将在浏览器会话结束时过期。

        [domain=domain]:定义要设置的 cookie 的domain。参数值可包含变量(1.11.5)。

        [httponly]:为cookie新增httponly属性。

        [samesite=strict|lax|none|$variable]:为cookie新增samesite属性,并使用以下值之一: Strict, Lax, None或使用变量(1.23.3)。如果变量值为空,则不会将samesite属性添加到 cookie 中;如果变量值解析成Strict, Lax或None,则会分配相应的值,否则会分配成Strict。

        [secure]:为cookie新增secure属性。

        [path=path]:指定要设置的cookie的path。

  • route:使用route方法时,代理服务器会在收到第一个请求时为客户端分配一个路由。该客户端的所有后续请求都将在 cookie 或 URI 中携带路由信息。这些信息将与server指令中的 "route"参数进行比较,以确定请求应代理到哪台服务器。如果未指定 "route"参数,路由名称将是 IP 地址和端口或 UNIX 域套接字路径的 MD5 哈希值的十六进制表示。如果指定的服务器无法处理请求,就会通过配置的负载均衡方法选择新的服务器,就像请求中没有路由信息那样。route方法的参数指定了可能包含路由信息的变量。第一个非空变量用于查找匹配的服务器。
map $cookie_jsessionid $route_cookie {
    ~.+\.(?P<route>\w+)$ $route;
}

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

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

    sticky route $route_cookie $route_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 分别指定了如何创建新会话和如何搜索现有会话的变量。这两个参数可指定多次,这时将使用第一个非空变量。

        会话存储在共享内存区域中,其name和size由zone参数配置。在 64 位平台上,1 兆字节的区域可存储约 4000 个会话。在timeout参数指定的时间内未被访问的会话会从区域中删除。默认情况下,timeout时间设置为 10 分钟。

        header参数(1.13.1)允许在收到上游服务器的响应头后立即创建会话。

        sync参数 (1.13.8) 可实现共享内存区的同步。

sticky_cookie_insert 

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

        自 1.5.7 版起,该指令已过时。

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值