目 录CONTENT

文章目录

Nginx负载均衡

简中仙
2022-09-07 / 0 评论 / 0 点赞 / 50 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2023-10-07,若内容或图片失效,请留言反馈。 本文如有错误或者侵权的地方,欢迎您批评指正!

HTTP负载均衡是基于HTTP协议的负载均衡应用。HTTP协议是建立在TCP协议之上的一种应用,是把TCP作为底层的传输协议,由于工作在第七层——应用层,因此它也被称为“七层负载均衡”。

TCP负载均衡是基于TCP协议的负载均衡应用。TCP协议是网络传输的基础协议,工作在网络层和传输层,因此也被称为“四层负载”。

1、负载均衡模块

Nginx负载均衡是由代理模块和上游(upstream)模块共同实现的,Nginx通过代理模块的反向代理功能将用户请求转发到上游服务器组,上游模块通过指定的负载均衡策略及相关的参数配置将用户请求转发到目标服务器上。上游模块可以与Nginx的代理指令(proxy_pass)、FastCGI协议指令(fastcgi_pass)、uWSGI协议指令(uwsgi_pass)、SCGI协议指令(scgi_pass)、memcached指令(memcached_pass)及gRPC协议指令(grpc_pass)实现多种协议后端服务器的负载均衡。

2、负载均衡策略

1、轮询

轮询(Round Robin)策略是Nginx配置中默认的负载均衡策略,该策略将客户端的请求依次分配给后端的服务器节点,对后端集群中的服务器实现轮流分配。轮询策略绝对均衡,且实现简单,但也会因后端服务器处理能力的不同而影响整个集群的处理性能。

加权轮询

在Nginx的轮询策略中,为了避免因集群中服务器性能的差异对整个集群性能造成影响,在轮询策略的基础上增加了权重参数,让使用者可以手动根据集群中各服务器的性能将请求数量按照权重比例分配给不同的被代理服务器。

平滑轮询

在加权轮询策略中,会按照权重的高低分配客户端请求,若按照高权重分配完再进行低权重分配的话,可能会出现的情况是高权重的服务器一直处于繁忙状态,压力相对集中。Nginx通过平滑轮询算法,使得上游服务器组中的每台服务器在总权重比例分配不变的情况下,均能参与客户端请求的处理,有效避免了在一段时间内集中将请求都分配给高权重服务器的情况发生。

配置样例如下:

http { 
    upstream backend { 
        server a weight=5; 
        server b weight=1; 
        server c weight=1; 
    } 
 
    server { 
        listen 80; 
 
        location / { 
            proxy_pass http://backend; 
        } 
    } 
}

2、一致性哈希

Nginx启用哈希的负载均衡策略,是用hash指令来设置的。哈希策略方法可以针对客户端访问的URL计算哈希值,对相同的URL请求,Nginx可以因相同的哈希值而将其分配到同一后端服务器。当后端服务器为缓存服务器时,将极大提高命中率,提升访问速度。

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

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

配置样例如下:

http { 
    upstream backend { 
        hash $request_uri;  # 以客户端请求URI为计算哈希值的key 
        hash $request_uri consistent;       # 以客户端请求URI为计算哈希值的key,使用一致性哈希算法
        server a weight=5; 
        server b weight=1; 
        server c weight=1; 
    } 
 
    server { 
        listen 80; 
 
        location / { 
            proxy_pass http://backend; 
        } 
    } 
}

3、IP哈希

IP哈希(IP Hash)负载均衡策略根据客户端IP计算出哈希值,然后把请求分配给该数值对应的被代理服务器。在哈希值不变且被代理服务器可用的前提下,同一客户端的请求始终会被分配到同一台被代理服务器上。IP哈希负载均衡策略常被应用在会话(Session)保持的场景。

配置样例如下:

http { 
    upstream backend { 
        ip_hash;            # 启用IP哈希负载均衡策略 
        server a weight=5; 
        server b weight=1; 
        server c weight=1; 
    } 
 
    server { 
        listen 80; 
 
        location / { 
            proxy_pass http://backend; 
        } 
    } 
}

4、最少连接

默认配置下轮询算法是把客户端的请求平均分配给每个被代理服务器,每个被代理服务器的负载大致相同,该场景有个前提就是每个被代理服务器的请求处理能力是相当的。如果集群中某个服务器处理请求的时间比较长,那么该服务器的负载也相对增高。在最少连接(least_conn)负载均衡策略下,会在上游服务器组中各服务器权重的前提下将客户端请求分配给活跃连接最少的被代理服务器,进而有效提高处理性能高的被代理服务器的使用率。

配置样例如下:

upstream backend { 
    least_conn;         # 启用最少连接负载均衡策略 
    server a weight=4; 
    server b weight=2; 
    server c weight=1; 
} 
 
server { 
    listen 80; 
    location / { 
        proxy_pass http://backend; 
    } 
}

5、随机负载算法

在Nginx集群环境下,每个Nginx均通过自身对上游服务器的了解情况进行负载均衡处理,这种场景下,很容易出现多台Nginx同时把请求都分配给同一台被代理服务器的场景,该场景被称为羊群行为(Herd Behavior)。Nginx基于两种选择的力量(Power of TwoChoices)原理,设计了随机(Random)负载算法。该算法使Nginx不再基于片面的情况了解使用固有的负载均衡策略进行被代理服务器的选择,而是随机选择两个,在经过比较后进行最终的选择。随机负载算法提供了一个参数two,当这个参数被指定时,Nginx会在考虑权重的前提下,随机选择两台服务器,然后用以下几种方法选择一个服务器。

  • 最少连接数,配置指令为least_conn,默认配置。
  • 响应头最短平均时间,配置指令为least_time=header,仅对商业版本有效。
  • 完整请求最短平均时间,配置指令为least_time=last_byte,仅对商业版本有效。

配置样例如下:

upstream backend { 
    random two least_conn; 
    server backend1.example.com; 
    server backend2.example.com; 
    server backend3.example.com; 
    server backend4.example.com; 
}

在只有单台Nginx服务器时,一般不建议使用随机负载算法。

3、负载均衡配置

1、负载均衡的长连接

当客户端通过浏览器访问HTTP服务器时,HTTP请求会通过TCP协议与HTTP服务器建立一条访问通道,当本次访问数据传输完毕后,该TCP连接会立即被断开,由于这个连接存在的时间很短,所以HTTP连接也被称为短连接。在HTTP/1.1版本中默认开启Connection:keep-alive,实现了HTTP协议的长连接,可以在一个TCP连接中传输多个HTTP请求和响应,减少了建立和关闭TCP连接的消耗和延迟,提高了传输效率。网络应用中,每个网络请求都会打开一个TCP连接,基于上层的软件会根据需要决定这个连接的保持或关闭。例如,FTP协议的底层也是TCP,是长连接。

默认配置下,HTTP协议的负载均衡与上游服务器组中被代理的连接都是HTTP/1.0版本的短连接。

upstream http_backend { 
    server 192.168.2.154:8080; 
    server 192.168.2.109:8080; 
    keepalive 32;                           # 长连接缓存池大小为32 
    keepalive_requests 2000;                # 每条长连接最大复用请求数为2000 
} 
 
server { 
    location /http/ { 
        proxy_pass http://http_backend; 
        proxy_http_version 1.1;             # 启用HTTP/1.1版本与被代理服务器建立连接 
        proxy_set_header Connection "";     # 清空发送被代理服务器请求头属性字段Connection 
                                                # 的内容 
    } 
}

对于FastCGI协议服务器,需要设置fastcgi_keep_conn指令启用长连接支持。

upstream fastcgi_backend { 
    server 192.168.2.154:9000; 
    server 192.168.2.109:9000; 
    keepalive 8;                            # 长连接缓存池大小为8 
} 
 
server { 
    ...  
        
    location /fastcgi/ { 
        fastcgi_pass fastcgi_backend; 
        fastcgi_keep_conn on;               # 启用长连接支持 
        ... 
    } 
}

SCGI和uWSGI协议没有长连接的概念。

Memcached协议(由ngx_http_memcached_module模块提供)的长连接配置,只需在upstream指令域中设置keepalive指令即可。

upstream memcached_backend { 
    server 127.0.0.1:11211; 
    server 10.0.0.2:11211; 
 
    keepalive 32;                           # 长连接缓存池大小为32 
} 
 
server { 
    ... 
 
    location /memcached/ { 
        set $memcached_key $uri;            # 设置$memcached_key为$uri 
        memcached_pass memcached_backend; 
    } 
}

2、upstream的容错机制

Nginx在upstream模块中默认的检测机制是通过用户的真实请求去检查被代理服务器的可用性,这是一种被动的检测机制,通过upstream模块中server指令的指令值参数max_fails及fail_timeout实现对被代理服务器的检测和熔断。

配置样例如下:

upstream http_backend { 
    # 10s内出现3次错误,该服务器将被熔断10s 
    server 192.168.2.154:8080 max_fails=3 fail_timeout=10s; 
    server 192.168.2.109:8080 max_fails=3 fail_timeout=10s; 
    server 192.168.2.108:8080 max_fails=3 fail_timeout=10s; 
    server 192.168.2.107:8080 max_fails=3 fail_timeout=10s; 
} 
 
server { 
    proxy_connect_timeout 5s;               # 与被代理服务器建立连接的超时时间为5s 
    proxy_read_timeout 10s;                 # 获取被代理服务器的响应最大超时时间为10s 
 
    # 当与被代理服务器通信出现指令值指定的情况时,认为被代理出错,并将请求转发给上游服务器组中 
    # 的下一个可用服务器 
    proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header; 
    proxy_next_upstream_tries 3;            # 转发请求最多3次 
    proxy_next_upstream_timeout 10s;        # 总尝试超时时间为10s 
 
    location /http/ { 
        proxy_pass http://http_backend; 
    } 
}

3、HTTP负载均衡配置

基于HTTP协议的负载均衡是通过HTTP代理模块(ngx_http_proxy_module)及上游模块(ngx_http_upstream_module)实现的,配置样例如下:

upstream http_backend { 
    server 192.168.2.154:8080; 
    server 192.168.2.109:8080; 
    keepalive 32;                                   # 长连接缓存池大小为32 
    keepalive_requests 2000;                                # 长连接复用请求的最大数为2000 
} 
 
server { 
    location /http/ { 
        proxy_pass http://http_backend; 
        proxy_http_version 1.1; 
        proxy_set_header Connection ""; 
    } 
}

4、FastCGI负载均衡配置

基于FastCGI协议的负载均衡是通过FastCGI模块(ngx_http_fastcgi_module)及上游模块(ngx_http_upstream_module)实现的,配置样例如下:

upstream php_backend { 
    server 192.168.2.154:8080; 
    server 192.168.2.109:8080; 
    keepalive 32; 
    keepalive_requests 2000; 
} 
 
server { 
    listen 8080; 
    root /opt/nginx-web/phpweb; 
    index index.php;                                        # 默认首页index.php 
    include fscgi.conf;                                     # 引入FastCGI配置 
 
    location ~ \.php(.*)$ { 
        fastcgi_pass   php_backend;                         # FastCGI服务器地址及端口 
        fastcgi_keep_conn on;                               # 启用长连接 
        fastcgi_index  index.php; 
 
        fastcgi_split_path_info    ^(.+\.php)(.*)$; # 获取$fastcgi_path_info变量值 
        fastcgi_param PATH_INFO    $fastcgi_path_info;      # 赋值给参数PATH_INFO 
        include  fastcgi.conf;      # 引入默认参数文件 
    } 
 
    error_page 404 /404.html; 
    error_page 500 502 503 504 /50x.html; 
}

5、uWSGI负载均衡配置

基于uWSGI协议的负载均衡是通过uWSGI模块(ngx_http_uwsgi_module)及上游模块(ngx_http_upstream_module)实现的,配置样例如下:

upstream uwsgi_backend { 
    server 192.168.2.154:8080; 
    server 192.168.2.109:8080; 
} 
 
server { 
    listen         8083; 
    server_name    localhost 
    charset UTF-8; 
 
    client_max_body_size 75M; 
 
    location / { 
        include uwsgi_params;               # 引入uWSGI默认参数配置 
        uwsgi_pass uwsgi://uwsgi_backend;   # 代理到上游服务器组uwsgi_backend 
        uwsgi_read_timeout 2; 
    } 
}

6、gRPC负载均衡配置

基于gRPC协议的负载均衡是通过gRPC模块(ngx_http_grpc_module)及上游模块(ngx_http_upstream_module)实现的,配置样例如下:

upstream grpc_backend { 
    server 192.168.2.154:8080; 
    server 192.168.2.109:8080; 
} 
 
server { 
    listen  80 http2;                       # 设置监听端口为80并启用HTTP/2协议支持 
    access_log /var/log/nginx/grpcs_access.log main; 
    location / { 
        grpc_pass grpc://grpc_backend;      # 代理到gRPC上游服务器组grpc_backend 
    } 
}

7、Memcached负载均衡配置

Memcached协议的负载均衡是通过Memcached模块(ngx_http_memcached_module)及上游模块(ngx_http_upstream_module)实现的,配置样例如下:

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

4、TCP/UDP负载均衡

Nginx的TCP/UDP负载均衡是应用Stream代理模块(ngx_stream_proxy_module)和Stream上游模块(ngx_stream_upstream_module)实现的。Nginx的TCP负载均衡与LVS都是四层负载均衡的应用,所不同的是,LVS是被置于Linux内核中的,而Nginx是运行于用户层的,基于Nginx的TCP负载可以实现更灵活的用户访问管理和控制。

1、TCP/UDP负载均衡

Nginx的Stream上游模块支持与Nginx HTTP上游模块一致的轮询(Round Robin)、哈希(Hash)及最少连接数(least_conn)负载均衡策略。Nginx默认使用轮询负载均衡策略,配置样例如下:

stream { 
    upstream backend { 
        server 192.168.2.145:389 weight=5; 
        server 192.168.2.159:389 weight=1; 
        server 192.168.2.109:389 weight=1; 
    } 
 
    server { 
        listen 389; 
        proxy_pass backend; 
    } 
}

哈希负载均衡策略可以通过客户端IP($remote_addr)实现简单的会话保持,其可将同一IP客户端始终转发给同一台后端服务器。

配置样例如下:

stream { 
    upstream backend { 
        hash $remote_addr; 
        server 192.168.2.145:389 weight=5; 
        server 192.168.2.159:389 weight=1; 
        server 192.168.2.109:389 weight=1; 
    } 
 
    server { 
        listen 389; 
        proxy_pass backend; 
    } 
}

哈希负载均衡策略通过指令参数consistent设定是否开启一致性哈希负载均衡策略。Nginx的一致性哈希负载均衡策略是采用Ketama一致性哈希算法,当后端服务器组中的服务器数量变化时,只会影响少部分客户端的请求。

配置样例如下

stream { 
    upstream backend { 
        hash $remote_addr consistent; 
        server 192.168.2.145:389 weight=5; 
        server 192.168.2.159:389 weight=1; 
        server 192.168.2.109:389 weight=1; 
    } 
 
    server { 
        listen 389; 
        proxy_pass backend; 
    } 
}

最少连接负载均衡策略,可以在后端被代理服务器性能不均时,在考虑上游服务器组中各服务器权重的前提下,将客户端连接分配给活跃连接最少的被代理服务器,从而有效提高处理性能高的被代理服务器的使用率。

配置样例如下:

stream { 
    upstream backend { 
        least_conn; 
        server 192.168.2.145:389 weight=5; 
        server 192.168.2.159:389 weight=1; 
        server 192.168.2.109:389 weight=1; 
    } 
 
    server { 
        listen 389; 
        proxy_pass backend; 
    } 
}

2、TCP/UDP负载均衡的容错机制

Nginx的TCP/UDP负载均衡在连接分配时也支持被动健康检测模式,如果与后端服务器建立连接失败,并在fail_timeout参数的时间内连续超过max_fails参数设置的次数,Nginx就会将该服务器置为不可用状态,并且在fail_timeout参数的时间内不再给该服务器分配连接。当fail_timeout参数的时间结束时将尝试分配连接检测该服务器是否恢复,如果可以建立连接,则判定为恢复。

配置样例如下:

stream { 
    upstream backend { 
        # 10s内出现3次错误,该服务器将被熔断10s 
        server 192.168.2.154:8080 max_fails=3 fail_timeout=10s;  
        server 192.168.2.109:8080 max_fails=3 fail_timeout=10s; 
        server 192.168.2.108:8080 max_fails=3 fail_timeout=10s; 
        server 192.168.2.107:8080 max_fails=3 fail_timeout=10s; 
    } 
 
    server { 
        proxy_connect_timeout 5s;           # 与被代理服务器建立连接的超时时间为5s 
        proxy_timeout 10s;          # 获取被代理服务器的响应最大超时时间为10s 
 
        # 当被代理的服务器返回错误或超时时,将未返回响应的客户端连接请求传递给upstream中的下一个服务器 
        proxy_next_upstream on; 
        proxy_next_upstream_tries 3;        # 转发尝试请求最多3次 
        proxy_next_upstream_timeout 10s;    # 总尝试超时时间为10s 
        proxy_socket_keepalive on;  # 开启SO_KEEPALIVE选项进行心跳检测 
        proxy_pass backend; 
    } 
}
0

评论区