nginx1.18.0之负载均衡

负载均衡器

HTTP流量代理到一组服务器

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
    
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

注释

http :定义接受http流量

upstream:定义转发组

server指令:定义组内的服务器

backup标记:当其他服务器down或者忙时才会请求到backup服务器

server模块:定义接受请求的虚拟服务器

location:定义匹配的url

proxy_pass:转发模块

HTTP负载均衡方法

介绍

跨多个应用程序实例的负载平衡是一种用于优化资源利用率,最大化吞吐量,减少延迟和确保容错配置的常用技术。

HTTP代理

开始使用对一组服务器的HTTP流量进行负载平衡,首先要使用upstream指令定义该组。该指令放置在HTTP模块中。

配置示例

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
    
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

注释

http模块中设置upstream代理服务器组backend

server 指定代理的服务器

backup是定义192.0.0.1服务器的属性,是备份属性,在backend 1\2正常状态下,不会将请求发送到备份属性的服务器上。

proxy_pass指令(fastcgi_pass,memcached_pass,scgi_pass,uwsgi_pass)将请求传递到服务器组

负载方法

NGINX开源支持四种负载平衡方法

Round Robin 轮询 (默认算法)

upstream backend {
   # no load balancing method is specified for Round Robin
   server backend1.example.com;
   server backend2.example.com;
}

最少连接数 :将请求发送到连接最少的服务器

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

IP哈希 :从客户端IP地址确定向其发送请求的服务器,保证了来自相同地址的请求将到达同一服务器

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

注释:

如果其中一台服务器需要从负载循环中删除,则使用down标记

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

通用哈希(也称url哈希)

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

解释

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

最短时间(仅nginx-plus):选择具有最低平均延迟和最低活动连接数的服务器

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

注释

判断平均延时最短的指标

header 从服务器接收第一个字节的时间

last_byte 从服务器接收完整响应的时间

last_byte inflight 从服务器接收完整响应的时间,考虑到请求不完整的时间。

随机 每个请求将传递到随机选择的服务器

upstream backend {
    random two least_time=last_byte;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
    server backend4.example.com;
}

注释

random two least_time=last_byte

two 随机选择两个机器提供服务,然后根据后面的参数 选择从服务器其中之一

参数:

least_conn 活动连接最少

least_time=hearder 从服务器接收响应标头的最短平均时间

least_time=last_byte 接收完整响应的最短平均时间的机器

使用场景 用于在多个负载平衡器传递请求到相同组的后端分布式环境

权重

upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

backend1.example.com权重为5 ;server backend2.example.com权重为1;192.0.0.1被标记为backup,则暂时不参与负载均衡。

每6个请求 ,5个发送到backend1.example.com

扩展为nginx-plus功能

(开源版本nginx不具有,请注意)

服务器慢启动

upstream backend {
    server backend1.example.com slow_start=30s;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

服务器缓慢启动功能可防止连接数过多而使最近恢复的服务器不堪重负,因为连接可能会超时并导致服务器再次标记为故障。

注释

设置服务器权重从0恢复到标准值的时间,默认值为0,缓慢的启动

扩展--状态值

upstream还能够为每一个设备设置状态值,这些状态值的含义分别例如以下:

down 表示单前的server临时不参与负载.

weight 默认为1 weight越大,负载的权重就越大。

max_fails :同意请求失败的次数默认为1. 当超过最大次数时,返回proxy_next_upstream 模块定义的错误.

fail_timeout :暂停的时间。

max_fails:失败次数。

backup: 其他全部的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。

max_conns 最大连接数

服务器权重

默认情况下,NGINX使用Round Robin方法根据请求的权重在组中的服务器之间分配请求。伪指令的weight参数server设置服务器的权重;默认值为1:

upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

在示例中,backend1.example.com具有weight 5;其他两台服务器的默认权重(1),但具有IP地址的192.0.0.1一台backup服务器被标记为服务器,除非其他两台服务器均不可用,否则不会接收请求。随着权重的这种配置,每的6请求,5发送到backend1.example.com和1对backend2.example.com。

服务器慢启动

服务器缓慢启动功能可防止连接已使最近恢复的服务器不堪重负,因为连接可能会超时并导致服务器再次标记为故障。

upstream backend {
    server backend1.example.com slow_start=30s;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

配置健康检查

NGINX可以持续测试您的HTTP上游服务器,避免出现故障的服务器,并可以将恢复的服务器正常地添加到负载平衡组中

TCP/UDP负载均衡方法

介绍

负载均衡是指多个后端服务器之间有效地分配网络流量。

在nginx中可以代理和负载平衡传输协议TCP通信。TCP是许多流行的应用程序和服务的协议,比如LDAP、MySQL和RTMP等。

nginx中也可以代理和负载平衡UDP流量。UDP(用户数据报协议)是许多流行的非应用程序(例如DNS 、syslog和RADIUS)的协议。

先决条件

1、开源版nginx需要编译安装--with-stream模块

2、通过TCP/UDP进行通信的应用程序,数据库或者服务

3、上游服务器,每个服务器运行应用程序,数据库或服务的相同实例

配置反向代理

1、创建一个stream{}块

2、server{}在顶级stream{}上下文中为每个虚拟服务器定义一个或多个配置块

3、在server{}每个服务器的配置块中,包括listen用于定义服务器侦听的IP地址和端口的指令

对于UDP通信,还包括udp参数。由于TCP是stream上下文的默认协议,因此tcp该listen指令没有参数;

4、包括该proxy_pass 指令以定义代理服务器或者服务器将流量转发到的上游组。

stream {

    server {
        listen     12345;
        #TCP traffic will be forwarded to the "stream_backend" upstream group
        proxy_pass stream_backend;
    }

    server {
        listen     12346;
        #TCP traffic will be forwarded to the specified server
        proxy_pass backend.example.com:12346;
    }

    server {
        listen     53 udp;
        #UDP traffic will be forwarded to the "dns_servers" upstream group
        proxy_pass dns_servers;
    }
    # ...
}

5、如果代理服务器具有多个网络接口,则可以选择将nginx配置为连接到上游服务器时使用特定的源IP地址。nginx之后的代理服务器配置为接受来自特定IP网络或者IP地址范围的连接

stream {
    # ...
    server {
        listen     127.0.0.1:12345;
        proxy_pass backend.example.com:12345;
        proxy_bind 127.0.0.1:12345;
    }
}

6、设置上游数据内容的缓存区

stream {
    # ...
    server {
        listen            127.0.0.1:12345;
        proxy_pass        backend.example.com:12345;
        proxy_buffer_size 16k;
    }
}

配置TCPUDP负载均衡

1、创建一组服务器,或者一个upstream组,其流量将实现负载均衡。upstream{}在顶级stream{}上下文中定义一个或多个配置块,并设置upstream组的名称。

stream {

    upstream stream_backend {
        # ...
    }

    upstream dns_servers {
        # ...
    }

    # ...
}

2、用upstream服务器填充上游组。在该upstream{}块内,server为每个上游服务器添加一个指令,指定其IP地址或者主机名和一个必须的端口号。

stream {

    upstream stream_backend {
        server backend1.example.com:12345;
        server backend2.example.com:12345;
        server backend3.example.com:12346;
        # ...
    }

    upstream dns_servers {
        server 192.168.136.130:53;
        server 192.168.136.131:53;
        # ...
    }

    # ...
}

3、配置上游组使用的负载均衡的方法。

轮询

最少连接

最少时间

随机

注释:

这些轮询方法都是在upstream模块内使用,所以根本来说是借助upstream的负载方法进行的配置。

最少连接时间

upstream stream_backend {
    least_time first_byte;
    server backend1.example.com:12345;
    server backend2.example.com:12345;
    server backend3.example.com:12346;
}

哈希

upstream stream_backend {
    hash $remote_addr;
    server backend1.example.com:12345;
    server backend2.example.com:12345;
    server backend3.example.com:12346;
}

随机

upstream stream_backend {
    random two least_time=last_byte;
    server backend1.example.com:12345;
    server backend2.example.com:12345;
    server backend3.example.com:12346;
    server backend4.example.com:12346;
}

在指定服务器后面设置参数

(权重、最大连接数等)

upstream stream_backend {
    hash   $remote_addr consistent;
    server backend1.example.com:12345 weight=5;
    server backend2.example.com:12345;
    server backend3.example.com:12346 max_conns=3;
}
upstream dns_servers {
    least_conn;
    server 192.168.136.130:53;
    server 192.168.136.131:53;
    # ...
}

配置健康检查

NGINX可以持续测试TCP或UDP上游服务器,避免出现故障的服务器,并将恢复的服务器正常地添加到负载平衡组中。

TCPUDP负载均衡配置示例

stream {
    upstream stream_backend {
        least_conn;
        server backend1.example.com:12345 weight=5;
        server backend2.example.com:12345 max_fails=2 fail_timeout=30s;
        server backend3.example.com:12345 max_conns=3;
    }
    
    upstream dns_servers {
        least_conn;
        server 192.168.136.130:53;
        server 192.168.136.131:53;
        server 192.168.136.132:53;
    }
    
    server {
        listen        12345;
        proxy_pass    stream_backend;
        proxy_timeout 3s;
        proxy_connect_timeout 1s;
    }
    
    server {
        listen     53 udp;
        proxy_pass dns_servers;
    }
    
    server {
        listen     12346;
        proxy_pass backend4.example.com:12346;
    }
}

注释
示例中,所有TCP与UDP代理相关功能都在stream块内进行配置,就像在http块中配置HTTP请求设置一样。

有两个明明upstream块,每个命名块包含三台服务器,他们承载彼此相同的内容。在没有upstream组中设定的服务器则需要标注端口信息。根据最小连接数负载平衡方法,连接在服务器之间分配:连接到活动连接最少的服务器。

三个server块:

1、第一个服务器侦听端口12345,并将所有TCP连接代理到上游服务器的stream_backend。如果stream调用的是它模块下的upstream则不可以使用协议

2、第二胎服务器侦听53端口,并将所有UDP数据报代理到dns_servers的上游组。如果udp未指定该参数,则默认是tcp连接

3、第三个虚拟服务器侦听端口12346,并代理到backend4.example.com的tcp连接,后者可以解析为轮询的方法实现负载平衡的多个IP地址。

HTTP运行状况检查

介绍

nginx可以连续测试上游服务器,避免出现故障的服务器,并可以将恢复的服务器正常地添加到负载平衡组中。

先决条件

对于被动健康检查使用开源nginx

负载均衡的HTTP上游服务器组

被动健康检查

对于被动运行状况检查,nginx会监视发生的事务,并尝试恢复失败的连接。如果仍然无法恢复交易,则将服务器标记为不可用,并暂时停止向服务器发送请求,直到再次将其标记为活动。

upstream backend {
    server backend1.example.com;
    server backend2.example.com max_fails=3 fail_timeout=30s;
}

注释:

fail_timeout 设置必须多次尝试失败才能将服务器标记为不可用的时间,以及将服务器标记为不可用的时间(默认为10秒)

max_files 设置在fail_timeout服务器被标记为不可用的时间段内必须发生的失败尝试次数(默认为1次尝试)

在示例中:如果NGINX无法在30秒内向服务器发送请求或没有收到3次响应,则它将服务器标记为30秒钟不可用

注意:

如果是只有一个服务器组,则fail_timeout和max_fails 参数将被忽略,服务器永远不会被标记为不可用。

服务器缓慢启动

最近恢复的服务器很容易被连接淹没,这可能导致服务器再次标记为不可用。慢速启动允许上游服务器在恢复或可用后将其权重从零逐渐恢复到其标称值。

upstream backend {
    server backend1.example.com slow_start=30s;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

请注意,如果组中只有一台服务器,则将slow_start忽略该参数,并且永远不会将服务器标记为不可用。慢速启动是NGINX Plus独有的。

TCP运行状况检查

介绍

NGINX可以持续测试您的TCP上游服务器,避免出现故障的服务器,并可以将恢复的服务器正常地添加到负载平衡组中。

先决条件

1、在stream中配置了TCP服务器的上游组

stream {
    #...
    upstream stream_backend {
    server backend1.example.com:12345;
    server backend2.example.com:12345;
    server backend3.example.com:12345;
   }
    #...
}

2、已经配置了将TCP传递到服务器组的服务器

stream {
    #...
    server {
        listen     12345;
        proxy_pass stream_backend;
    }
    #...
}
被动TCP运行状况检查

如果连接上游服务器的尝试超时或导致错误,NGINX可以将服务器标记为不可用,并在指定的时间内停止向其发送请求。

fail_timeout –在指定的连接尝试次数内必须失败的时间,才能将服务器视为不可用。此外,NGINX将服务器标记为不可用后的时间。

max_fails –在指定时间内NGINX认为服务器不可用的失败尝试次数。

默认值为10秒数和1尝试次数。

30秒内将这些参数设置为2次失败

upstream stream_backend {
    server backend1.example.com:12345 weight=5;
    server backend2.example.com:12345 max_fails=2 fail_timeout=30s;
    server backend3.example.com:12346 max_conns=3;
}
服务器缓慢启动

最近恢复的上游服务器很容易被连接淹没,这可能导致服务器再次标记为不可用。慢速启动允许上游服务器在恢复或可用后将其权重从零逐渐恢复到其标称值。

upstream backend {
    server backend1.example.com:12345 slow_start=30s;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

请注意,如果组中只有一台服务器,则将slow_start忽略该参数,并且永远不会将服务器标记为不可用。

UDP健康检查

先决条件

1、配置上下文中的上游服务器组来处理UDP网络流量

2、配置了将UDP数据报传递到上游服务器组的服务器

被动UDP健康检查

特定时间段内连续失败的连接尝试次数是使用上游服务器的max_fails参数设置的(默认值为1)

时间段由fail_timeout参数设置(默认值为10秒)。

该参数还设置了NGINX标记服务器后认为服务器不可用的时间。

示例显示了如何在60秒内将这些参数设置为2次失败

upstream dns_upstream {
    server 192.168.136.130:53 fail_timeout=60s;
    server 192.168.136.131:53 fail_timeout=60s;
}

注释

fail_timeout只是设置了失败的秒数,2次是在upstream中设置的

接受代理协议

配置NGINX接受PROXY协议,将负载均衡器或代理的IP地址重写为PROXY协议标头中接收到的负载均衡器或代理,配置客户端IP地址的简单日志记录以及启用PROXY协议在NGINX和TCP上游服务器之间。

介绍

通过PROXY协议,NGINX以接收通过代理服务器和负载均衡器传递的客户端连接信息。

使用PROXY协议,NGINX可以从HTTP,SSL,HTTP / 2,SPDY,WebSocket和TCP学习原始IP地址。知道客户端的原始IP地址对于为网站设置特定语言,保留IP地址拒绝列表或仅出于日志记录和统计目的可能很有用。

通过PROXY协议传递的信息是客户端IP地址,代理服务器IP地址以及两个端口号。

获取客户端的原始IP的方法:

使用\(proxy_protocol_addr和\)proxy_protocol_port变量捕获原始客户端IP地址和端口。

\(remote_addr和\)remote_port变量捕捉负载平衡器的IP地址和端口。

配置nginx接受代理协议

要将NGINX配置为接受PROXY协议标头,请在或块中的块中将proxy_protocol参数添加到listen指令中。

http {
    #...
    server {
        listen 80   proxy_protocol;
        listen 443  ssl proxy_protocol;
        #...
    }
}
   
stream {
    #...
    server {
        listen 12345 proxy_protocol;
        #...
    }
}

现在可以将\(proxy_protocol_addr和\)proxy_protocol_port变量用于客户端IP地址和端口

注释

这是配置TCPUDP时的设置,如果是HTTP代理时设置则需要编译安装并指定 Real-IP模块

将负载均衡器的IP地址更改为客户端IP地址

将负载均衡服务器或者TCP代理的地址替换为proxy协议收到的客户端IP地址。

通过HTTP和stream Real-IP模块来完成。

使用\(remote_addr和\)remote_port变量保留客户端的实际IP地址和端口。

\(realip_remote_addr和\)realip_remote_port变量保留负载均衡器的IP地址和端口。

操作如下:

1、确保已经将nginx配置为接受proxy协议标头

2、确保nginx安装中包含HTTP和stream Real-IP模块

nginx -V 2>和1  | grep- 'http_realip_module'nginx 
-V 2> &1  | grep- 'stream_realip_module'

如果没有安装,则使用这些模块重新编译nginx.

3、在HTTP、stream或者两者的set_real_ip_from 伪指令中,指定TCP代理或者负载均衡器的IP地址或CIDR地址范围

server {
    #...
    set_real_ip_from 192.168.1.0/24;
   #...
}

4、在上下文中,通过伪指令指定参数,将负载均衡器的IP地址更改为proxy协议标头接收的客户端的IP地址

http {
    server {
        #...
        real_ip_header proxy_protocol;
      }
}
记录原始IP地址

1、对于HTTP,配置nginx使用$proxy_protocol_addr带有proxy_set_header伪指令的变量将客户端IP地址传递给上游服务器

http  { 
    proxy_set_header  X-Real-IP        $ proxy_protocol_addr ; 
    proxy_set_header  X-Forwarded-For  $ proxy_protocol_addr ; 
}

2、将$proxy_protocol_addr变量添加到log_format指令(HTTP或Stream)

在HTTP块中

http {
    proxy_set_header X-Real-IP       $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}

在stream块中

stream {
    #...
    log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
                      '$protocol $status $bytes_sent $bytes_received '
                      '$session_time';
}
用于与上游TCP连接的proxy协议

对于TCP流,可以为nginx和上游服务器之间的连接启用proxy协议。要启用proxy协议,则如下配置

stream {
    server {
        listen 12345;
        proxy_pass example.com:12345;
        proxy_protocol on;
    }
}
示例
http {
    log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';
    #...

    server {
        server_name localhost;

        listen 80   proxy_protocol;
        listen 443  ssl proxy_protocol;

        ssl_certificate      /etc/nginx/ssl/public.example.com.pem;
        ssl_certificate_key  /etc/nginx/ssl/public.example.com.key;

        location /app/ {
            proxy_pass       http://backend1;
            proxy_set_header Host            $host;
            proxy_set_header X-Real-IP       $proxy_protocol_addr;
            proxy_set_header X-Forwarded-For $proxy_protocol_addr;
        }
    }
} 

stream {
    log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time';
    #...
    server {
        listen              12345 ssl proxy_protocol;

        ssl_certificate     /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/cert.key;

        proxy_pass          backend.example.com:12345;
        proxy_protocol      on;
    }
}

该示例假定NGINX前面有一个负载平衡器来处理所有传入的HTTPS流量,例如Amazon ELB。NGINX在端口443()上接受HTTPS流量,在端口12345上接受TCP流量,并接受通过PROXY协议从负载均衡器传递的客户端IP地址(和块中指令的参数)。listen 443 ssl;proxy_protocollistenhttp {}stream {}

NGINX终止HTTPS流量(ssl_certificate和ssl_certificate_key指令),并将解密的数据代理到后端服务器:

对于HTTP: proxy_pass http://backend1
对于TCP: proxy_pass backend.example.com:12345
它包括带有proxy_set_header指令的客户端IP地址和端口

指令中$proxy_protocol_addr指定的变量log_format还将客户端的IP地址传递到HTTP和TCP的日志中。

此外,TCP服务器(该块)将其自己的PROXY协议数据发送到其后端服务器(该指令)。

posted @ 2020-10-13 10:21  热气球!  阅读(436)  评论(0编辑  收藏  举报