Nginx配置七层负载均衡

2021/12 14 19:12

Nginx配置七层负载均衡
原创2021-12-13 06:50·死牛胖子
Nginx配置七层负载均衡

Nginx 一般用于七层负载均衡,其吞吐量有一定限制。为了提升系统整体吞吐量,会在 DNS 与 Nginx 之间引入接入层,比如使用LVS(软负载均衡器)、F5(硬负载均衡器)做四层负载均衡。整体的请求流转如下图所示,即首先 DNS 解析到 LVS/F5,然后 LVS/F5 转发给 Nginx,再由 Nginx 转发给后端上游服务器。

Nginx配置七层负载均衡
对于一般开发人员来说,我们只需要关注 Nginx 层面即可,LVS/F5 一般由运维工程师维护。

四层负载均衡:根据 IP 地址 + 端口将报文转发到上游服务器
七层负载均衡:根据 应用层协议(Http协议)的主机名、URL + 端口将报文转发到上游服务器

负载均衡配置
配置 upstream 上游服务器列表

upstream backend {
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2;
}
通过 proxy_pass 进行使用

location / {
proxy_pass http://backend;
}
负载均衡算法

round-robin
轮询,默认负载均衡算法,通过配合 weight 的配置可以实现基于权重的轮询

ip_hash
对客户IP地址使用哈希算法进行负载均衡,会将相同IP的请求转发给相同的上游服务器

upstream backend {
ip_hash;
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2;
}
hash key [consistent]
对某一个 key 使用哈希算法进行负载均衡,consistent 表示使用一致性哈希算法。

使用哈希算法的问题是,当添加/删除一台服务器时,将导致很多 key 被重新负载到不同的服务器,
这可能会导致后端服务器出问题,使用一致性哈希算法,当添加/删除一台服务器时,
只有少数 key 会被重新负载到不同的服务器,影响面会小很多。

upstream backend {
hash $uri;
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2;
}
也可以在 location 段中设置变量作为 key

location / {
set $consistent_key $arg_cat;
if ($consistent_key = “”) {
set $consistent_key $request_uri;
}
}

upstream backend {
hash $consistent_key consistent;
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2;
}
least_conn
将请求负载到最少活跃连接的上游服务器,如果配置的服务器较少,则转而使用基于权重的轮询算法

Nginx 商业版还提供了 least_time 算法,即基于最小平均响应时间进行负载

失败重试
分为 upstream server 和 proxy_pass 两部分配置

upstream backend {
server 192.168.2.1:8080 max_fails=2 fail_timeout=10s weight=1;
server 192.168.2.1:8090 max_fails=2 fail_timeout=10s weight=2;
}
当 fail_timeout 时间内请求失败 max_fails 次,则认为该上游服务器不可用,然后摘掉该服务器,fail_timeout 时间后会再次将该服务器加入到存活服务器列表进行重试。

location / {
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
proxy_sned_timeout 5s;

proxy_next_upstream error timeout;
proxy_next_upstream_timeout 10s;
proxy_next_upstream_tries 2;

proxy_pass http://backend;
}
当请求出错,或者超时,会重试下一台上游服务器。

健康检查
Nginx 对上游服务器的健康检查默认采用的是惰性策略。Nginx 商业版提供了 health_check 进行主动健康检查,也可以通过集成
nginx_upstream_check_module 模块来进行主动健康检查。

nginx_upstream_check_module 支持 TCP 心跳和 HTTP 心跳来实现健康检查。

TCP 心跳检查

upstream backend {
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2;
check interval=3000 rise=1 fail=3 timeout=2 type=tcp;
}
interval:检测时间间隔,此处为3s一次
fail:检测失败多少次后,上游服务器被标记为不存活
rise:检测成功多少次后,上游服务器被标记为存活,并可以处理请求
timeout:检测请求超时时间配置
HTTP 心跳检查

upstream backend {
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2;
check interval=3000 rise=1 fail=3 timeout=2 type=http;
check_http_send “HEAD /status HTTP/1.0\r\n\r\n”;
check_http_expect_alive http_2xx http_3xx;
}
check_http_send:检查时发的 HTTP 请求内容
check_http_expect_alive:当上游服务器返回匹配的状态码时,被认为存活
检查间隔时间不能太短,否则可能因为心跳检查包太多造成上游服务器挂掉,同时要设置合理的超时时间

备份配置
设置该服务器为备份服务器,当所有主服务器都不存活时,请求会转发给备份服务器

upstream backend {
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2 backup;
}
不可用配置
upstream backend {
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2 down;
}
长连接配置
配置每个 worker 进程与上游服务器可缓存的空闲长连接最大数量,当超出这个数量时,最近最少使用的连接将被关闭。

upstream backend {
server 192.168.2.1:8080 weight=1;
server 192.168.2.1:8090 weight=2;
keepalive 100;
}
空闲连接池太小,连接不够用,需要不断新建连接
空闲连接池太大,空闲连接太多,还没使用就超时
建议只对小报文开启长连接