跳到主要内容

[toc]

nginx七层负载均衡概述

nginx七层负载均衡官方文档简介版

nginx七层负载均衡官方文档详细版

1.nginx负载均衡概念

  • 后端web服务往往要承载大量并发请求,单台服务器难以负荷,后端使用多台web服务器组成集群,前端使用nginx作为负载均衡,将请求分散的打到后端服务器集群中,实现负载的分发。这样会大大提升系统的吞吐率、请求性能、高容灾等等。

示意图

iShot2020-06-1821.03.51

2.nginx负载均衡upstream

2.1 语法

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

2.2 负载均衡方法

总揽

开源nginx调度算法

调度算法概述
Round Robin轮询(rr),按时间顺序逐一分配到不同的后端服务器(默认)
Weight Round Robin加权轮询(wrr),weight值越大,分配到的访问几率越高
IP Hash每个请求按访问IP的hash结果分配,这样来自同一IP的请求固定访问同一个后端服务器
Generic Hash(url_hash)按照访问URL的hash结果来分配请求,每个URL定向到同一个后端
Least Connections最少链接数,哪个机器链接数少就分发

2.2.1 Round Robin 轮询

请求在服务器之间平均分配,同时考虑了服务器权重。默认情况下使用此方法(没有启用它的指令)

upstream backend {
# 没有配置就是Round Robin 轮询
server backend1.example.com;
server backend2.example.com;
}

2.2.2 Weight Round Robin 加权轮询

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

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

2.2.3 Least Connections 最少连接

将活动连接最少的请求发送到服务器,再次考虑服务器权重

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

2.2.4 IP Hash

从客户端IP地址确定向其发送请求的服务器。在这种情况下,可以使用IPv4地址的前三个八位位组或整个IPv6地址来计算哈希值。该方法保证了来自同一地址的请求将到达同一服务器,除非该请求不可用

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

如果其中一台服务器需要暂时从负载平衡循环中删除,则可以使用down参数对其进行标记,以保留客户端IP地址的当前哈希值。该服务器要处理的请求将自动发送到组中的下一个服务器

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

2.2.5 Generic Hash (url_hash)

发送请求到的服务器由用户定义的键决定,该键可以是文本字符串、变量或组合。例如,键可以是成对的源IP地址和端口,或者是一个URI,如本例所示

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

哈希指令的可选consistent参数支持ketama一致哈希负载平衡。请求根据用户定义的散列键值均匀地分布在所有上游服务器上。如果上游服务器被添加到或从上游组移除,只有几个键被重新映射,在负载平衡的缓存服务器或其他积累状态的应用程序的情况下最小化缓存丢失。

应用场景

有一个服务器集群A,需要对外提供文件下载,由于文件上传量巨大,没法存储到服务器磁盘中,所以用到了第三方云存储来做文件存储。服务器集群A收到客户端请求之后,需要从云存储中下载文件然后返回,为了省去不必要的网络带宽和下载耗时,在服务器集群A上做了一层临时缓存(缓存一个月)。由于是服务器集群,所以同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。在此类场景下,为了使得缓存命中率提高,很适合使用url_hash策略,同一个url(也就是同一个资源请求)会到达同一台机器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取,既减少了带宽,也减少的下载时间。

upstream somestream {
hash $request_uri;
server 192.168.1.1:8080;
server 192.168.1.2:8080;
server 192.168.1.3:8080;
}

server {
listen 80 default;
server_name test.cdn.com;
charset utf-8;
location /get {
proxy_pass http://somestream;
}
}

2.2.6 random

每个请求将传递到随机选择的服务器,如果two指定了参数,首先,NGINX考虑服务器权重随机选择两个服务器,然后使用指定的方法选择这些服务器之一

  • least_conn –活动连接最少
  • least_time=header(NGINX Plus)–从服务器接收响应标头的最短平均时间($upstream_header_time
  • least_time=last_byte(NGINX Plus)–从服务器接收完整响应的最短平均时间($upstream_response_time
upstream backend {
random two least_time=last_byte;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
server backend4.example.com;
}

随机负载平衡方法应该用于分布式环境,其中多个负载平衡器将请求传递给同一组后端。对于负载平衡器对所有请求都有完整视图的环境,可以使用其他负载平衡方法,比如轮询、最少连接和最少时间。

nginx plus增加的调度算法

调度算法概述
Least Time选择具有最低平均延迟和最低数量的活动连接

第三方调度算法

调度算法概述
fair按照服务器端的响应时间来分配请求,响应时间短的优先分配

2.2.7 fair

按照服务器端的响应时间来分配请求,响应时间短的优先分配。

upstream dynamic_zuoyu {
fair; #实现响应时间短的优先分配
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
}

2.3 后端web服务器在前端nginx负载均衡调度中的状态

警告

ip_hash和bakcup不能一起写,否则语法检测会有报错

状态概述
down当前的server暂时不参与负载均衡
backup预留的备份服务器
max_fails允许请求失败的次数
fail_timeout经过max_fails失败后, 服务暂停时间
max_conns限制最大的接收连接数

配置示例

upstream www {
server 10.0.0.50:80 down;
server 10.0.0.51:80 backup;
server 10.0.0.52:80 max_fails=1 fail_timeout=10s;
}

location / {
proxy_pass http://www;
include proxy_params;
}

2.4 配置示例

# upstream例子
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
}
server {
location / {
proxy_pass http://backend;
}
}

3.配置健康检查

http健康检查官方文档

3.1 被动健康检查

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

使用块中server指令的参数为每个上游服务器定义了将上游服务器标记为不可用的条件upstream

  • fail_timeout –设置必须多次尝试失败才能将服务器标记为不可用的时间,以及将服务器标记为不可用的时间(默认为10秒)。
  • max_fails –设置在fail_timeout服务器标记为不可用的时间段内必须发生的失败尝试次数(默认为1次尝试)。

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

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

4.nginx负载均衡配置示例

实验环境

服务器角色ip主机名
lb10.0.0.10lb01
web0110.0.0.51web01
web0210.0.0.52web02

4.1 负载均衡lb配置

编辑nginx配置文件

upstream www {
server 10.0.0.51;
server 10.0.0.52;
}

server {
listen 80;
server_name _;

location / {
proxy_pass http://www;
}
}

4.2 web01配置

编辑nginx配置文件

server {
listen 80;
root /code;
index index.html;
}

创建网站根目录

mkdir /code
cat > /code/index.html <<EOF
<html>
<title> Code1</title>
<body bgcolor="red">
<h1> Code1 </h1>
</body>
</html>
EOF

4.3 web02配置

编辑nginx配置文件

server {
listen 80;
root /code;
index index.html;
}

创建网站根目录

mkdir /code
cat > /code/index.html <<EOF
<html>
<title> Code1</title>
<body bgcolor="blue">
<h1> Code2 </h1>
</body>
</html>
EOF

4.4 浏览器访问lb IP地址

第一次访问

iShot2020-06-1821.03.10

第二次访问

iShot2020-06-1723.09.57

因为是使用默认的rr轮询算法,因此请求会依次转发到web01和web02