Nginx负载均衡06

负载均衡

将用户请求根据对应的算法, 分发到集群中的一台服务器上进行处理

作用

  • 提升并发处理能力

  • 提高单点故障宕机容错能力, 实现高可用

  • 通过添加或减少服务器数量, 增强可扩展性

  • 在负载均衡器上进行过滤, 提高系统安全性

常用实现方式

用户手动选择

比较原始的方式, 即提供不同线路, 由用户自己选择访问服务器

DNS轮询

由域名注册商解析同一域名到多主机IP, 随机访问不同IP, 也可以实现简单的负载均衡

但存在可靠性低(DNS缓存), 不均衡的问题

四/七层负载均衡

开放式系统互联模型 - OSI(open system interconnection)

image-20211217232125273

四层负载均衡(传输层)

基于IP+Port实现, 包括硬件和软件实现方式:

  • 硬件: F5 BIG-IP 、Radware等
  • 软件: LVS、Nginx、Hayproxy等
七层负载均衡(应用层)

基于虚拟的URL或主机IP实现

  • 软件: Nginx、Hayproxy等

四层负载均衡数据是在底层就进行分发, 而七层负载均衡则是在最顶端分发, 所以四层负载均衡效率更高

四层负载均衡不识别域名, 而七层负载均衡识别域名

一般实际环境使用四层负载(LVS) + 七层负载均衡(Nginx)

Nginx七层负载均衡

需要使用proxy_pass代理模块, 在反向代理的基础上将用户请求根据指定算法分发到[upstream虚拟服务池]

指令

upstram指令

用于定义一组服务器, 可以是不同端口, 也可以是监听TCP和Unix socket的服务器, 权重不指定, 默认为1

1
2
3
4
语法:
upstream name{...}
位置:
http块
server指令

用于指定后端服务器的名称及参数, 可以使用域名/IP/端口或Unix socket

1
2
3
4
语法:
server name[parameters]
位置:
upstream

实现流程

image-20220603230545450

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 配置负载均衡服务器 192.168.253.134
http {
...
upstream serverpool{
server 192.168.253.135;
server 192.168.253.136;
server 192.168.253.137;
}
server{
listen 80;
server_name test.project.com;
location /{
proxy_pass http://serverpool;
}
}
}

# 配置服务端服务器 192.168.253.135 / 192.168.253.136 / 192.168.253.137
http {
...
server{
listen 80;
server_name localhost;
location /{
default_type text/plain;
return 200 '<h1>192.168.253.137</h1>';
}
}
}

实现结果

image-20211218190642925

负载均衡状态

状态 概述
down 当前server不参与服务
backup 预留备份服务器
max_fails 允许请求失败次数, 默认1
fail_timeout 请求失败后, 服务暂停时间, 默认10s
max_conns 限制最大的接收连接数, 默认0, 不限制
1
2
3
4
5
upstream serverpool{
server 192.168.253.135 down;
server 192.168.253.136 backup;
server 192.168.253.137 max_fails=3 fail_timeout=15;
}

使用配置之后, 由于浏览器缓存问题, 可能出现仍然访问到135服务器的状况, 可以用curl请求验证配置生效

image-20220604005521986

负载均衡策略

Nginx的upstream支持六种分配算法, 分别是:

算法 概述
轮询 默认方式, 无需配置
weight 依权重点数分配
ip_hash 依据IP分配
least_conn 最少连接分配
url_hash 依据URL分配
fair 依响应时间分配
轮询策略

不做任何配置, 默认就是使用轮询策略

weight加权

也叫加权轮询, 使用weight=number设置server服务器的权重, 权重越大, 分配到的概率就越大, 主要是为了针对工作环境中不同配置的服务器配置

1
2
3
4
5
upstream serverpool{
server 192.168.253.135 weight=10;
server 192.168.253.136 weight=5;
server 192.168.253.137 weight=5;
}
ip_hash策略

通过请求客户端的IP,所计算出的哈希值定位到同一后端服务器上, 之后该客户端的请求均访问同一服务器, 可以解决用户session共享问题, 但无法保证后端服务器的负载均衡, 且设置后权重等配置将失效

1
2
3
4
5
6
upstream serverpool{
ip_hash;
server 192.168.253.135;
server 192.168.253.136;
server 192.168.253.137;
}
least_conn策略

将请求转发给连接数较少的后端服务器上, 可以避免某些占用时间长的请求, 连续分发到同一服务器上, 达到更好的负载均衡效果

1
2
3
4
5
6
upstream serverpool{
least_conn;
server 192.168.253.135;
server 192.168.253.136;
server 192.168.253.137;
}
url_hash策略

通过用户访问URL的哈希计算结果来分配请求访问目标, 使每一个URL定向到同一个后端服务器, 使其提高缓存命中率, 避免不必要的资源下载

1
2
3
4
5
6
upstream serverpool{
hash $request_uri;
server 192.168.253.135;
server 192.168.253.136;
server 192.168.253.137;
}
fair策略

依据客户端请求页面大小、加载时间长短智能分发. 但不是nginx内建均衡算法, 需要引入第三方模块

1
2
3
4
5
6
upstream serverpool{
fair;
server 192.168.253.135;
server 192.168.253.136;
server 192.168.253.137;
}

添加nginx-upstream-fair模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# https://github.com/gnosek/nginx-upstream-fair 下载fair压缩包
$ wget https://nginx.org/download/nginx-1.14.0.tar.gz # 对照本机版本下载nginx包
$ unzip nginx-upstream-fair
$ tar -zxvf nginx-1.14.0.tar.gz

$ cd nginx-1.14.0
$ vi src/http/ngx_http_upstream.h # 打开文件
/ngx_http_upstream_srv_conf_s # 找到关键字
131 in_port_t default_port; # 131行添加内容
$ sudo apt install build-essential libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev libxslt1-dev libgd-dev libgroip-dev # 安装编译依赖
$ pwd ../nginx-upstream-fair # 记录下module路径
$ nginx -V # 复制nginx模块配置
$ ./configure [nginx原有配置] --add-module=[fair-module路径]
$ make
$ sudo mv /usr/sbin/nginx /usr/sbin/nginx_old # 备份
$ sudo cp objs/nginx /usr/sbin/nginx # 替换nginx
# $ sudo service nginx restart # 重启nginx
$ make upgrade # 更新nginx

实际案例

特定资源负载均衡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 配置负载均衡服务器 192.168.253.134
http {
...
upstream video_pool{
server 192.168.253.135;
server 192.168.253.136;
}
upstream file_pool{
server 192.168.253.137;
server 192.168.253.138;
}
server{
listen 80;
server_name localhost;
location /video{
proxy_pass http://video_pool;
}
location /file{
proxy_pass http://file_pool;
}
}
}

image-20220604175807846

image-20220604175831716

对不同域名实现负载均衡

修改客户端本地hosts文件(C:\Windows\System32\drivers\etc\hosts), 添加内容

1
2
192.168.253.134 local1.project.com
192.168.253.134 local2.project.com

修改服务器nginx配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
upstream local1{
server 192.168.253.135;
server 192.168.253.136;
}
upstream local2{
server 192.168.253.137;
server 192.168.253.138;
}

server{
listen 80;
server_name local1.project.com;
location /{
proxy_pass http://local1;
}
}
server{
listen 80;
server_name local2.project.com;
location /{
proxy_pass http://local2;
}
}

image-20220604181016412

image-20220604181034312

带URL重写的负载均衡

重写请求中以file开头的路由, 到new路由中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
upstream rewrite_pool{
server 192.168.253.135 weight=2;
server 192.168.253.136 weight=1;
server 192.168.253.137 weight=1;
}
server{
listen 80;
server_name localhost;
location /file/{
rewrite ^(/file/.*/) /new/$1 last;
}
location /new{
proxy_pass http://rewrite_pool;
}
}

Nginx 四层负载均衡

Nginx 的四层协议转发、代理、负载均衡, 是通过stream模块实现的. 允许配置一组TCP/UDP等协议的监听, 然后通过proxy_pass转发请求, 通过upstream添加多个后端服务, 实现负载均衡

添加stream模块支持

1
2
3
4
5
6
$ sudo mv /usr/sbin/nginx /usr/sbin/nginx_old	# 备份
$ nginx -V # 复制nginx模块配置
$ ./configure [nginx原有配置] --with-stream # 添加stream模块
$ make
$ sudo cp objs/nginx /usr/sbin/nginx # 替换nginx
$ sudo service nginx restart # 重启nginx

image-20220604185419081

stream模块指令

stream指令

提供在其中指定流服务器的配置文件上下文, 和http块同级

1
2
3
4
语法:
stream{...}
位置:
main
upstream指令

与upstream模块中类似, 但位置处于stream块内部

实际案例

访问负载均衡分发服务器的8088端口时, 将请求分发到两台服务器的redis服务中

1
2
3
4
5
6
7
8
9
10
11
12
# 设置192.168.253.134服务器的nginx配置
stream{
upstream redis_backend{
server 192.168.253.135:6379;
server 192.168.253.136:6379;
}
server{
listen 8088;
proxy_pass redis_backend;
}
}

结果:

image-20220605002708958